@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.
Files changed (403) hide show
  1. package/package.json +352 -0
  2. package/src/checks/index.ts +24 -0
  3. package/src/checks/lib/astro-site-url.ts +30 -0
  4. package/src/checks/lib/i18n.ts +30 -0
  5. package/src/checks/result-helpers.ts +102 -0
  6. package/src/checks/suppressions-config.ts +195 -0
  7. package/src/index.ts +14 -0
  8. package/src/integration/README.md +38 -0
  9. package/src/integration/adapters.ts +143 -0
  10. package/src/integration/crm-buffer.ts +491 -0
  11. package/src/integration/dispatch.ts +106 -0
  12. package/src/integration/funnel.ts +379 -0
  13. package/src/integration/index.ts +56 -0
  14. package/src/integration/lifecycle.ts +155 -0
  15. package/src/integration/orchestration.ts +439 -0
  16. package/src/integration/port-barrel.ts +124 -0
  17. package/src/integration/port.ts +143 -0
  18. package/src/integration/qstash.ts +134 -0
  19. package/src/integration/sharding.ts +133 -0
  20. package/src/integration/tests/deliver-event.test.ts +52 -0
  21. package/src/integration/tests/dispatch.test.ts +88 -0
  22. package/src/integration/tests/funnel-bridge.test.ts +46 -0
  23. package/src/integration/tests/hub-runtime.test.ts +128 -0
  24. package/src/integration/tests/lifecycle.test.ts +69 -0
  25. package/src/integration/tests/qstash.test.ts +83 -0
  26. package/src/integration/tests/sharding.test.ts +64 -0
  27. package/src/integration/vitest.config.ts +8 -0
  28. package/src/integration-adapter-supabase-crm/adapter.ts +437 -0
  29. package/src/integration-adapter-supabase-crm/client.ts +605 -0
  30. package/src/integration-adapter-supabase-crm/index.ts +28 -0
  31. package/src/integration-adapter-supabase-crm/pipedrive-sync-target.ts +482 -0
  32. package/src/integration-adapter-supabase-crm/supabase-rest.ts +89 -0
  33. package/src/integration-adapter-supabase-crm/tenant-registry.ts +334 -0
  34. package/src/integration-adapter-supabase-crm/tests/change-balance.pbt.test.ts +83 -0
  35. package/src/integration-adapter-supabase-crm/tests/funnel-persistence.test.ts +409 -0
  36. package/src/integration-adapter-supabase-crm/tests/lifecycle-sync.test.ts +288 -0
  37. package/src/integration-adapter-supabase-crm/tests/stage-map.test.ts +80 -0
  38. package/src/integration-adapter-supabase-crm/vitest.config.ts +8 -0
  39. package/src/integration-adapter-supabase-crm/worker.ts +223 -0
  40. package/src/observability/conventions.ts +93 -0
  41. package/src/observability/env-resolver.ts +57 -0
  42. package/src/observability/index.ts +57 -0
  43. package/src/observability/metric-registry.ts +184 -0
  44. package/src/observability/otlp-converter.ts +125 -0
  45. package/src/observability/otlp-json.ts +135 -0
  46. package/src/observability/otlp-transport.ts +68 -0
  47. package/src/observability/pusher.ts +142 -0
  48. package/src/observability/redact.ts +27 -0
  49. package/src/observability/tests/conventions.test.ts +100 -0
  50. package/src/observability/tests/metric-registry.test.ts +117 -0
  51. package/src/observability/tests/otlp-converter.pbt.test.ts +77 -0
  52. package/src/observability/tests/otlp-converter.test.ts +157 -0
  53. package/src/observability/tests/otlp-json.test.ts +120 -0
  54. package/src/observability/tests/pusher.test.ts +75 -0
  55. package/src/observability/tests/redact.pbt.test.ts +71 -0
  56. package/src/observability/tests/redact.test.ts +37 -0
  57. package/src/observability/typed-refs.ts +137 -0
  58. package/src/observability/vitest.config.ts +8 -0
  59. package/src/ontology/analytics/matomo-binding.yaml +172 -0
  60. package/src/ontology/analytics/matomo-fleet.registry.yaml +26 -0
  61. package/src/ontology/analytics/messkanon.yaml +151 -0
  62. package/src/ontology/archetype-registry.ts +61 -0
  63. package/src/ontology/archetypes/components/brand-label.yaml +19 -0
  64. package/src/ontology/archetypes/components/copyright.yaml +19 -0
  65. package/src/ontology/archetypes/components/currency-aware-price-display.yaml +19 -0
  66. package/src/ontology/archetypes/components/currency-selector.yaml +19 -0
  67. package/src/ontology/archetypes/components/footer-promo.yaml +19 -0
  68. package/src/ontology/archetypes/components/lang-switcher.yaml +19 -0
  69. package/src/ontology/archetypes/components/layout.yaml +19 -0
  70. package/src/ontology/archetypes/components/live-photo.yaml +20 -0
  71. package/src/ontology/archetypes/components/material-credit.yaml +20 -0
  72. package/src/ontology/archetypes/components/media.yaml +21 -0
  73. package/src/ontology/archetypes/components/nachweis-card.yaml +34 -0
  74. package/src/ontology/archetypes/components/nachweis-detail.yaml +43 -0
  75. package/src/ontology/archetypes/components/nachweis-list.yaml +37 -0
  76. package/src/ontology/archetypes/components/nachweis-verify.yaml +31 -0
  77. package/src/ontology/archetypes/components/not-found.yaml +22 -0
  78. package/src/ontology/archetypes/components/offer-capacity.yaml +21 -0
  79. package/src/ontology/archetypes/components/passport-header.yaml +19 -0
  80. package/src/ontology/archetypes/components/passport-provenance.yaml +20 -0
  81. package/src/ontology/archetypes/components/passport-score-grid.yaml +20 -0
  82. package/src/ontology/archetypes/components/passport-star-map.yaml +20 -0
  83. package/src/ontology/archetypes/components/person-profile.yaml +20 -0
  84. package/src/ontology/archetypes/components/pulsar.yaml +20 -0
  85. package/src/ontology/archetypes/components/responsive-image.yaml +19 -0
  86. package/src/ontology/archetypes/components/scroll-to-top.yaml +22 -0
  87. package/src/ontology/archetypes/components/social-meta.yaml +20 -0
  88. package/src/ontology/archetypes/components/structured-data.yaml +19 -0
  89. package/src/ontology/archetypes/index.json +1003 -0
  90. package/src/ontology/archetypes/index.yaml +821 -0
  91. package/src/ontology/archetypes/sections/approach.yaml +23 -0
  92. package/src/ontology/archetypes/sections/article-list.yaml +30 -0
  93. package/src/ontology/archetypes/sections/audience-cards.yaml +30 -0
  94. package/src/ontology/archetypes/sections/breadcrumbs.yaml +21 -0
  95. package/src/ontology/archetypes/sections/chat-widget.yaml +37 -0
  96. package/src/ontology/archetypes/sections/comparison-cards.yaml +31 -0
  97. package/src/ontology/archetypes/sections/controlled-responsibility-block.yaml +34 -0
  98. package/src/ontology/archetypes/sections/credits.yaml +29 -0
  99. package/src/ontology/archetypes/sections/donation-card.yaml +53 -0
  100. package/src/ontology/archetypes/sections/donation-use.yaml +23 -0
  101. package/src/ontology/archetypes/sections/dynamic-status-block.yaml +35 -0
  102. package/src/ontology/archetypes/sections/faq-list.yaml +26 -0
  103. package/src/ontology/archetypes/sections/final-cta.yaml +53 -0
  104. package/src/ontology/archetypes/sections/hero-decision-card.yaml +65 -0
  105. package/src/ontology/archetypes/sections/hero.yaml +50 -0
  106. package/src/ontology/archetypes/sections/impact.yaml +23 -0
  107. package/src/ontology/archetypes/sections/markdown.yaml +43 -0
  108. package/src/ontology/archetypes/sections/mountain-journey.yaml +43 -0
  109. package/src/ontology/archetypes/sections/navigation.yaml +20 -0
  110. package/src/ontology/archetypes/sections/notausgang-block.yaml +41 -0
  111. package/src/ontology/archetypes/sections/open-source-registry.yaml +26 -0
  112. package/src/ontology/archetypes/sections/ownership-block.yaml +57 -0
  113. package/src/ontology/archetypes/sections/people.yaml +48 -0
  114. package/src/ontology/archetypes/sections/price-card.yaml +50 -0
  115. package/src/ontology/archetypes/sections/problem.yaml +23 -0
  116. package/src/ontology/archetypes/sections/send-message.yaml +63 -0
  117. package/src/ontology/archetypes/sections/service-metadata-block.yaml +40 -0
  118. package/src/ontology/archetypes/sections/social-proof.yaml +27 -0
  119. package/src/ontology/archetypes/sections/transparency.yaml +32 -0
  120. package/src/ontology/archetypes/sections/trust-strip.yaml +42 -0
  121. package/src/ontology/archetypes/sections/video-section.yaml +27 -0
  122. package/src/ontology/archetypes/sections/women.yaml +29 -0
  123. package/src/ontology/biome-token-projection.ts +229 -0
  124. package/src/ontology/biomes/check-concrete-blueprint.yaml +118 -0
  125. package/src/ontology/biomes/handwerk-material-warm.yaml +135 -0
  126. package/src/ontology/biomes/nonprofit-trust.yaml +123 -0
  127. package/src/ontology/blueprints/offer.yaml +39 -0
  128. package/src/ontology/blueprints/prompts/local-market-signal.md +13 -0
  129. package/src/ontology/blueprints/prompts/website-local-narrative.md +24 -0
  130. package/src/ontology/blueprints/ratgeber.yaml +62 -0
  131. package/src/ontology/blueprints/website-local.yaml +309 -0
  132. package/src/ontology/blueprints/website-service.yaml +84 -0
  133. package/src/ontology/capabilities/lead.submit.yaml +44 -0
  134. package/src/ontology/cosmic/index.ts +48 -0
  135. package/src/ontology/cosmic/moon-catalog.ts +173 -0
  136. package/src/ontology/cosmic/planet-catalog.ts +82 -0
  137. package/src/ontology/cosmic/star-catalog.ts +337 -0
  138. package/src/ontology/enums.ts +159 -0
  139. package/src/ontology/external-surfaces/index.ts +158 -0
  140. package/src/ontology/external-surfaces/jsonld-types.yaml +135 -0
  141. package/src/ontology/external-surfaces/sitemap-shape.yaml +6 -0
  142. package/src/ontology/external-surfaces/url-schema.yaml +95 -0
  143. package/src/ontology/growth/events/contact-email-click.yaml +21 -0
  144. package/src/ontology/growth/events/contact-form-submit.yaml +25 -0
  145. package/src/ontology/growth/events/contact-phone-click.yaml +21 -0
  146. package/src/ontology/growth/events/contact-route-click.yaml +21 -0
  147. package/src/ontology/growth/events/contact-submit.yaml +28 -0
  148. package/src/ontology/growth/events/contact-whatsapp-click.yaml +21 -0
  149. package/src/ontology/growth/events/cta-click.yaml +30 -0
  150. package/src/ontology/growth/events/donation-confirmed.yaml +32 -0
  151. package/src/ontology/growth/events/donation-form-start.yaml +21 -0
  152. package/src/ontology/growth/events/donation-form-submit.yaml +29 -0
  153. package/src/ontology/growth/events/donation-intent.yaml +29 -0
  154. package/src/ontology/growth/events/form-error.yaml +27 -0
  155. package/src/ontology/growth/events/form-start.yaml +21 -0
  156. package/src/ontology/growth/events/form-submit.yaml +21 -0
  157. package/src/ontology/growth/events/outbound-click.yaml +25 -0
  158. package/src/ontology/growth/events/page-view.yaml +24 -0
  159. package/src/ontology/growth/events/passport-view.yaml +28 -0
  160. package/src/ontology/growth/events/star-map-navigate.yaml +30 -0
  161. package/src/ontology/index.ts +165 -0
  162. package/src/ontology/manifest.ts +344 -0
  163. package/src/ontology/operations/index.ts +1 -0
  164. package/src/ontology/schemas/biome.ts +303 -0
  165. package/src/ontology/schemas/capability.ts +104 -0
  166. package/src/ontology/schemas/constellation.ts +114 -0
  167. package/src/ontology/schemas/dns-records.ts +53 -0
  168. package/src/ontology/schemas/index.ts +95 -0
  169. package/src/ontology/schemas/manifest-resolver.ts +123 -0
  170. package/src/ontology/schemas/page-entry.ts +213 -0
  171. package/src/ontology/schemas/section-archetype.ts +109 -0
  172. package/src/ontology/schemas/site-family.ts +98 -0
  173. package/src/ontology/schemas/system/growth.ts +80 -0
  174. package/src/ontology/schemas/system/integrations.ts +143 -0
  175. package/src/ontology/schemas/system/manifest.ts +492 -0
  176. package/src/ontology/schemas/system/page-output.ts +99 -0
  177. package/src/ontology/schemas/system/release.ts +58 -0
  178. package/src/ontology/schemas/system/text.ts +58 -0
  179. package/src/ontology/schemas/system.ts +53 -0
  180. package/src/ontology/shared-section-props/body-fragments.ts +182 -0
  181. package/src/ontology/shared-section-props/catalog.ts +195 -0
  182. package/src/ontology/shared-section-props/common.ts +178 -0
  183. package/src/ontology/shared-section-props/index.ts +34 -0
  184. package/src/ontology/shared-section-props/visual-header.ts +163 -0
  185. package/src/ontology/site-families/charity-donation-trust/cultural-rules.yaml +6 -0
  186. package/src/ontology/site-families/charity-donation-trust/family.yaml +44 -0
  187. package/src/ontology/site-families/charity-donation-trust/linguistic-rules.yaml +6 -0
  188. package/src/ontology/site-families/check-quality-operator/cultural-rules.yaml +6 -0
  189. package/src/ontology/site-families/check-quality-operator/family.yaml +40 -0
  190. package/src/ontology/site-families/check-quality-operator/linguistic-rules.yaml +6 -0
  191. package/src/ontology/site-families/handwerk-trust-engineering/cultural-rules.yaml +6 -0
  192. package/src/ontology/site-families/handwerk-trust-engineering/family.yaml +53 -0
  193. package/src/ontology/site-families/handwerk-trust-engineering/linguistic-rules.yaml +6 -0
  194. package/src/ontology/tests/catalogs.pbt.test.ts +89 -0
  195. package/src/ontology/tests/enums.test.ts +203 -0
  196. package/src/ontology/tests/sternsystem-owner.test.ts +63 -0
  197. package/src/ontology/vitest.config.ts +8 -0
  198. package/src/passport/dht-sign.test.ts +99 -0
  199. package/src/passport/dht-sign.ts +73 -0
  200. package/src/passport/identity-sign.test.ts +134 -0
  201. package/src/passport/identity-sign.ts +85 -0
  202. package/src/passport/index.ts +53 -0
  203. package/src/passport/key-rotate.ts +133 -0
  204. package/src/passport/schema.ts +198 -0
  205. package/src/passport/sign.ts +225 -0
  206. package/src/passport/tests/schema.pbt.test.ts +93 -0
  207. package/src/passport/tests/schema.test.ts +222 -0
  208. package/src/passport/vitest.config.ts +8 -0
  209. package/src/share/agent/api-catalog.ts +77 -0
  210. package/src/share/agent/capability.ts +68 -0
  211. package/src/share/agent/dns-aid.test.ts +74 -0
  212. package/src/share/agent/dns-aid.ts +53 -0
  213. package/src/share/agent/fleet-catalog.ts +149 -0
  214. package/src/share/agent/index.ts +29 -0
  215. package/src/share/agent/knowledge.ts +96 -0
  216. package/src/share/agent/manifest.ts +126 -0
  217. package/src/share/agent/mcp-card.ts +63 -0
  218. package/src/share/agent/omit-empty.ts +77 -0
  219. package/src/share/agent/openapi.ts +157 -0
  220. package/src/share/agent/proof.ts +61 -0
  221. package/src/share/attribution-display.ts +86 -0
  222. package/src/share/check-hints.ts +38 -0
  223. package/src/share/content/entity-id.ts +65 -0
  224. package/src/share/content/index.ts +16 -0
  225. package/src/share/content/merge.ts +86 -0
  226. package/src/share/content/resolve-field-path.ts +39 -0
  227. package/src/share/content/substitute-deep.ts +47 -0
  228. package/src/share/content-discipline/index.ts +14 -0
  229. package/src/share/content-discipline/parsers.ts +66 -0
  230. package/src/share/content-discipline/types.ts +118 -0
  231. package/src/share/content-reference.ts +333 -0
  232. package/src/share/counter-utils.ts +75 -0
  233. package/src/share/css-value-normalize.ts +48 -0
  234. package/src/share/dev-props-validator.ts +131 -0
  235. package/src/share/entitlement.ts +172 -0
  236. package/src/share/env.d.ts +73 -0
  237. package/src/share/feature-policy.ts +367 -0
  238. package/src/share/formula-eval.ts +364 -0
  239. package/src/share/fs/index.ts +96 -0
  240. package/src/share/i18n/localization.ts +57 -0
  241. package/src/share/image-provider.ts +314 -0
  242. package/src/share/index.ts +86 -0
  243. package/src/share/knowledge/claim.ts +129 -0
  244. package/src/share/knowledge/derivation.ts +55 -0
  245. package/src/share/knowledge/freshness.ts +127 -0
  246. package/src/share/knowledge/index.ts +23 -0
  247. package/src/share/knowledge/ledger.ts +222 -0
  248. package/src/share/knowledge/plan.ts +122 -0
  249. package/src/share/knowledge/source.ts +170 -0
  250. package/src/share/legal/translation-policy.ts +133 -0
  251. package/src/share/material-credits.ts +181 -0
  252. package/src/share/middleware/language-redirect.ts +49 -0
  253. package/src/share/offer-capacity.ts +149 -0
  254. package/src/share/onboarding-yaml/index.ts +162 -0
  255. package/src/share/page.ts +351 -0
  256. package/src/share/redirects.test.ts +62 -0
  257. package/src/share/redirects.ts +54 -0
  258. package/src/share/rfc0042-utils.ts +95 -0
  259. package/src/share/runtime-context.ts +70 -0
  260. package/src/share/schemas/claim-records.ts +69 -0
  261. package/src/share/schemas/claims.ts +150 -0
  262. package/src/share/schemas/effects.ts +212 -0
  263. package/src/share/schemas/features.ts +147 -0
  264. package/src/share/schemas/horizontal-align.ts +22 -0
  265. package/src/share/schemas/icon-color.ts +27 -0
  266. package/src/share/schemas/index.ts +43 -0
  267. package/src/share/schemas/live-photo.ts +53 -0
  268. package/src/share/schemas/material-credit.ts +292 -0
  269. package/src/share/schemas/media.ts +220 -0
  270. package/src/share/schemas/navigation.ts +74 -0
  271. package/src/share/schemas/page-base.ts +33 -0
  272. package/src/share/schemas/participant.ts +247 -0
  273. package/src/share/schemas/person.ts +24 -0
  274. package/src/share/schemas/print.ts +93 -0
  275. package/src/share/schemas/section-background.ts +106 -0
  276. package/src/share/schemas/section-body.ts +138 -0
  277. package/src/share/schemas/section-cards.ts +37 -0
  278. package/src/share/schemas/section-cta.ts +74 -0
  279. package/src/share/schemas/section-header.ts +77 -0
  280. package/src/share/schemas/section-image.ts +77 -0
  281. package/src/share/schemas/section-motion.ts +52 -0
  282. package/src/share/schemas/section-shell.ts +63 -0
  283. package/src/share/schemas/section-stats.ts +37 -0
  284. package/src/share/schemas/site-background.ts +78 -0
  285. package/src/share/schemas/standard-list-item.ts +38 -0
  286. package/src/share/scripts/external-links.ts +45 -0
  287. package/src/share/scripts/gsap-counter.ts +168 -0
  288. package/src/share/scripts/gsap-mountain-journey.ts +236 -0
  289. package/src/share/scripts/gsap-parallax.ts +50 -0
  290. package/src/share/scripts/gsap-reveal.ts +65 -0
  291. package/src/share/scripts/gsap-stagger.ts +54 -0
  292. package/src/share/scripts/index.ts +25 -0
  293. package/src/share/scripts/inline-number-animation.ts +120 -0
  294. package/src/share/scripts/lenis.ts +109 -0
  295. package/src/share/scripts/live-photos.ts +250 -0
  296. package/src/share/scripts/lordicon.ts +94 -0
  297. package/src/share/scripts/orchestrator.ts +138 -0
  298. package/src/share/scripts/scheduler.ts +53 -0
  299. package/src/share/scripts/video-player.ts +116 -0
  300. package/src/share/semantic/ai.ts +140 -0
  301. package/src/share/semantic/block-extraction.ts +52 -0
  302. package/src/share/semantic/block-extractors/index.ts +502 -0
  303. package/src/share/semantic/breadcrumbs.ts +120 -0
  304. package/src/share/semantic/build-page.ts +309 -0
  305. package/src/share/semantic/business-projection.ts +278 -0
  306. package/src/share/semantic/derived-prices-loader.ts +36 -0
  307. package/src/share/semantic/extract.ts +118 -0
  308. package/src/share/semantic/feed.ts +124 -0
  309. package/src/share/semantic/ids.ts +76 -0
  310. package/src/share/semantic/image-sitemap.ts +153 -0
  311. package/src/share/semantic/index.ts +36 -0
  312. package/src/share/semantic/jsonld/article.ts +47 -0
  313. package/src/share/semantic/jsonld/breadcrumb.ts +47 -0
  314. package/src/share/semantic/jsonld/collection-list.ts +30 -0
  315. package/src/share/semantic/jsonld/context.ts +46 -0
  316. package/src/share/semantic/jsonld/faq.ts +49 -0
  317. package/src/share/semantic/jsonld/initiative.ts +53 -0
  318. package/src/share/semantic/jsonld/organization.ts +101 -0
  319. package/src/share/semantic/jsonld/person.ts +71 -0
  320. package/src/share/semantic/jsonld/service.ts +80 -0
  321. package/src/share/semantic/jsonld/shared.ts +31 -0
  322. package/src/share/semantic/jsonld/types.ts +18 -0
  323. package/src/share/semantic/jsonld/webpage.ts +98 -0
  324. package/src/share/semantic/jsonld/website.ts +27 -0
  325. package/src/share/semantic/jsonld.ts +75 -0
  326. package/src/share/semantic/llms-policy.ts +74 -0
  327. package/src/share/semantic/llms.ts +394 -0
  328. package/src/share/semantic/markdown-hygiene.ts +68 -0
  329. package/src/share/semantic/markdown-twin-provenance.ts +242 -0
  330. package/src/share/semantic/models.ts +402 -0
  331. package/src/share/semantic/organization-profile.ts +160 -0
  332. package/src/share/semantic/output-projection.ts +131 -0
  333. package/src/share/semantic/page-builders/markdown-page.ts +84 -0
  334. package/src/share/semantic/page-markdown.ts +234 -0
  335. package/src/share/semantic/page-utils.ts +125 -0
  336. package/src/share/semantic/price-marker-resolver.ts +92 -0
  337. package/src/share/semantic/robots.ts +127 -0
  338. package/src/share/semantic/update-stamp.ts +136 -0
  339. package/src/share/shared-context.ts +177 -0
  340. package/src/share/string-utils.ts +19 -0
  341. package/src/share/tests/api-catalog.test.ts +97 -0
  342. package/src/share/tests/breadcrumbs.test.ts +126 -0
  343. package/src/share/tests/build-page-price-markers.test.ts +160 -0
  344. package/src/share/tests/capability.test.ts +107 -0
  345. package/src/share/tests/claim.test.ts +90 -0
  346. package/src/share/tests/content-ref-index.test.ts +328 -0
  347. package/src/share/tests/create-dev-props-validator.test.ts +38 -0
  348. package/src/share/tests/derivation.test.ts +39 -0
  349. package/src/share/tests/dev-props-validator.test.ts +88 -0
  350. package/src/share/tests/fleet-catalog.test.ts +134 -0
  351. package/src/share/tests/formula-eval.test.ts +619 -0
  352. package/src/share/tests/freshness.test.ts +60 -0
  353. package/src/share/tests/hero-section-numbering-parity.test.ts +51 -0
  354. package/src/share/tests/image-sitemap.test.ts +101 -0
  355. package/src/share/tests/jsonld-service.test.ts +282 -0
  356. package/src/share/tests/knowledge.test.ts +86 -0
  357. package/src/share/tests/ledger.test.ts +125 -0
  358. package/src/share/tests/llms-0789.test.ts +63 -0
  359. package/src/share/tests/manifest.test.ts +100 -0
  360. package/src/share/tests/markdown-twin-provenance.test.ts +108 -0
  361. package/src/share/tests/mcp-card.test.ts +57 -0
  362. package/src/share/tests/onboarding-yaml.test.ts +111 -0
  363. package/src/share/tests/ontology-role-by-cosmic-name.test.ts +28 -0
  364. package/src/share/tests/openapi.test.ts +116 -0
  365. package/src/share/tests/organization-jsonld.test.ts +74 -0
  366. package/src/share/tests/output-projection.test.ts +61 -0
  367. package/src/share/tests/plan.test.ts +97 -0
  368. package/src/share/tests/price-marker-resolver.test.ts +141 -0
  369. package/src/share/tests/proof.test.ts +72 -0
  370. package/src/share/tests/resolve-field-path.test.ts +52 -0
  371. package/src/share/tests/source.test.ts +81 -0
  372. package/src/share/tests/substitute-deep.test.ts +65 -0
  373. package/src/share/tests/text-normalize.pbt.test.ts +143 -0
  374. package/src/share/tests/text-normalize.test.ts +285 -0
  375. package/src/share/tests/twin-path.test.ts +43 -0
  376. package/src/share/text-normalize.ts +548 -0
  377. package/src/share/text-position.ts +19 -0
  378. package/src/share/types/hls-js-light.d.ts +16 -0
  379. package/src/share/visibility.ts +167 -0
  380. package/src/share/vitest.config.ts +8 -0
  381. package/src/share/wrap-inline-numbers.ts +139 -0
  382. package/src/surface/blueprint-schema.ts +314 -0
  383. package/src/surface/blueprint-types.ts +256 -0
  384. package/src/surface/blueprint.ts +300 -0
  385. package/src/surface/breaker.ts +57 -0
  386. package/src/surface/decision-composer.ts +156 -0
  387. package/src/surface/eligibility.ts +372 -0
  388. package/src/surface/evidence-records.ts +97 -0
  389. package/src/surface/fleet.ts +60 -0
  390. package/src/surface/geo.ts +170 -0
  391. package/src/surface/governance.ts +146 -0
  392. package/src/surface/index.ts +216 -0
  393. package/src/surface/io/index.ts +18 -0
  394. package/src/surface/io/surface-module-context-io.ts +60 -0
  395. package/src/surface/io/visibility-outcomes-io.ts +46 -0
  396. package/src/surface/module-context.ts +120 -0
  397. package/src/surface/substance.ts +161 -0
  398. package/src/surface/tests/eligibility.pbt.test.ts +137 -0
  399. package/src/surface/tests/eligibility.test.ts +302 -0
  400. package/src/surface/types.ts +289 -0
  401. package/src/surface/visibility.ts +57 -0
  402. package/src/surface/vitest.config.ts +8 -0
  403. package/tsconfig.json +17 -0
@@ -0,0 +1,138 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>Provides a standard orchestration logic for layout-global scripts across all Warpgogol projects.</purpose>
4
+ <non-goals>
5
+ <item>Do not handle project-specific feature logic directly.</item>
6
+ </non-goals>
7
+ </MODULE_CONTRACT>
8
+ <CHANGE_SUMMARY>
9
+ <item>Created standard layout orchestrator in @warpgogol/werkstatt-shared/share/scripts to reduce code duplication in apps.</item>
10
+ </CHANGE_SUMMARY>
11
+ */
12
+
13
+ // @ai-invariant: This is a high-risk module. Preserve its core logic and minimize external side effects during modification.
14
+
15
+ import { applyExternalLinkBehavior } from "./external-links.ts";
16
+ import { initLordIconOnDemand } from "./lordicon.ts";
17
+ import { initLenis } from "./lenis.ts";
18
+
19
+ export interface OrchestrationOptions {
20
+ headerOffset?: number;
21
+ /** RFC-0040: opt in to GSAP stat counter animation. Default false. */
22
+ counters?: boolean;
23
+ /** RFC-0041: opt in to GSAP inline number animation for prose sections. Default false. */
24
+ inlineNumbers?: boolean;
25
+ /** RFC-0106: opt in to GSAP scroll-triggered reveal animations. Default false. */
26
+ reveal?: boolean;
27
+ /** RFC-0106: opt in to GSAP parallax for [data-parallax-speed] elements. Default false. */
28
+ parallax?: boolean;
29
+ /** RFC-0106: opt in to GSAP stagger for [data-motion-stagger] parents. Default false. */
30
+ stagger?: boolean;
31
+ /** RFC-0202: opt in to the living-photos runtime for [data-live-photo] elements. Default false. */
32
+ livePhotos?: boolean;
33
+ /** RFC-0210: opt in to the lazy feature-video player (Plyr + hls.js) for [data-video-player]. Default false. */
34
+ videoPlayers?: boolean;
35
+ /** RFC-0205: opt in to Lenis smooth scroll. Default false — avoids loading the 17 KB bundle when not needed. */
36
+ smoothScroll?: boolean;
37
+ }
38
+
39
+ const has = (selector: string) => document.querySelector(selector) instanceof Element;
40
+
41
+ /**
42
+ * Runs the standard set of browser initializations required for all Warpgogol platform sites.
43
+ */
44
+ export async function runStandardLayoutOrchestration(
45
+ options: OrchestrationOptions = {},
46
+ ): Promise<void> {
47
+ const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
48
+
49
+ // 1. External links security (mandatory)
50
+ if (has("a[href]")) {
51
+ if (document.readyState === "loading") {
52
+ document.addEventListener("DOMContentLoaded", () => applyExternalLinkBehavior(), {
53
+ once: true,
54
+ });
55
+ } else {
56
+ applyExternalLinkBehavior();
57
+ }
58
+ }
59
+
60
+ // 2. LordIcon hydration (mandatory on demand)
61
+ if (has("lord-icon")) {
62
+ initLordIconOnDemand();
63
+ }
64
+
65
+ // 3. Lenis smooth scroll (opt-in via smoothScroll: true)
66
+ if (options.smoothScroll) {
67
+ await initLenis({
68
+ prefersReducedMotion,
69
+ headerOffset: options.headerOffset ?? 80,
70
+ });
71
+ }
72
+
73
+ // 4. GSAP stat counter (RFC-0040 — opt-in via counters: true)
74
+ // Note: has() check removed; initGsapCounter internally guards against empty sections.
75
+ if (options.counters) {
76
+ const { scheduleTask } = await import("./scheduler.ts");
77
+ scheduleTask(async () => {
78
+ const { initGsapCounter } = await import("./gsap-counter.ts");
79
+ await initGsapCounter({ prefersReducedMotion });
80
+ });
81
+ }
82
+
83
+ // 5. GSAP inline number animation (RFC-0041 — opt-in via inlineNumbers: true)
84
+ if (options.inlineNumbers && has(".js-inline-number")) {
85
+ const { scheduleTask } = await import("./scheduler.ts");
86
+ scheduleTask(async () => {
87
+ const { initInlineNumberAnimation } = await import("./inline-number-animation.ts");
88
+ await initInlineNumberAnimation({ prefersReducedMotion });
89
+ });
90
+ }
91
+
92
+ // 6. RFC-0106: reveal animations (opt-in via reveal: true).
93
+ if (options.reveal && has("[data-motion-reveal]")) {
94
+ const { scheduleTask } = await import("./scheduler.ts");
95
+ scheduleTask(async () => {
96
+ const { initGsapReveal } = await import("./gsap-reveal.ts");
97
+ await initGsapReveal({ prefersReducedMotion });
98
+ });
99
+ }
100
+
101
+ // 7. RFC-0106: parallax animations (opt-in via parallax: true).
102
+ if (options.parallax && has("[data-parallax-speed]")) {
103
+ const { scheduleTask } = await import("./scheduler.ts");
104
+ scheduleTask(async () => {
105
+ const { initGsapParallax } = await import("./gsap-parallax.ts");
106
+ await initGsapParallax({ prefersReducedMotion });
107
+ });
108
+ }
109
+
110
+ // 8. RFC-0106: stagger animations (opt-in via stagger: true).
111
+ if (options.stagger && has("[data-motion-stagger]")) {
112
+ const { scheduleTask } = await import("./scheduler.ts");
113
+ scheduleTask(async () => {
114
+ const { initGsapStagger } = await import("./gsap-stagger.ts");
115
+ await initGsapStagger({ prefersReducedMotion });
116
+ });
117
+ }
118
+
119
+ // 9. RFC-0202: living photos runtime (opt-in via livePhotos: true).
120
+ // Only the in-viewport/tap triggers carry [data-trigger]; the autoplay path is native.
121
+ if (options.livePhotos && has("[data-live-photo][data-trigger]")) {
122
+ const { scheduleTask } = await import("./scheduler.ts");
123
+ scheduleTask(async () => {
124
+ const { initLivePhotos } = await import("./live-photos.ts");
125
+ await initLivePhotos({ prefersReducedMotion });
126
+ });
127
+ }
128
+
129
+ // 10. RFC-0210: feature-video player (opt-in via videoPlayers: true).
130
+ // Lazy Plyr + hls.js, gated on [data-video-player]; nothing loads without a feature video.
131
+ if (options.videoPlayers && has("video[data-video-player]")) {
132
+ const { scheduleTask } = await import("./scheduler.ts");
133
+ scheduleTask(async () => {
134
+ const { initVideoPlayers } = await import("./video-player.ts");
135
+ await initVideoPlayers({ prefersReducedMotion });
136
+ });
137
+ }
138
+ }
@@ -0,0 +1,53 @@
1
+ /***************************************************************
2
+ <MODULE_CONTRACT>
3
+ <purpose>Facilitates task scheduling and processing in a non-blocking manner, optimizing idle time for execution.</purpose>
4
+ <non-goals>
5
+ <item>Do not handle task prioritization or dependencies between tasks.</item>
6
+ <item>Do not parse raw content or manage data fetching here.</item>
7
+ <item>Do not own transport or configuration orchestration for tasks.</item>
8
+ </non-goals>
9
+ </MODULE_CONTRACT>
10
+ <CHANGE_SUMMARY>
11
+ <item>Tidied by compass.changesummary.tidy; see git history for prior entries.</item>
12
+ </CHANGE_SUMMARY>
13
+ ***************************************************************/
14
+
15
+ // @ai-invariant: This is a high-risk module. Preserve its core logic and minimize external side effects during modification.
16
+ // --- Scheduler Start ---
17
+ type Task = () => Promise<void> | void;
18
+
19
+ const taskQueue: Task[] = [];
20
+ let isTaskRunnerScheduled = false;
21
+ function processTasks(deadline?: { timeRemaining: () => number; didTimeout: boolean }) {
22
+ isTaskRunnerScheduled = false;
23
+
24
+ // If no deadline (setTimeout fallback), simulate a budget
25
+ const timeRemaining = deadline ? () => deadline.timeRemaining() : () => 16;
26
+
27
+ while (taskQueue.length > 0 && (timeRemaining() > 1 || (deadline?.didTimeout ?? false))) {
28
+ const task = taskQueue.shift();
29
+ if (task) {
30
+ void task();
31
+ }
32
+ }
33
+
34
+ if (taskQueue.length > 0) {
35
+ isTaskRunnerScheduled = true;
36
+ if ("requestIdleCallback" in window) {
37
+ window.requestIdleCallback(processTasks, { timeout: 1000 });
38
+ } else {
39
+ setTimeout(processTasks, 50);
40
+ }
41
+ }
42
+ }
43
+ export function scheduleTask(task: Task) {
44
+ taskQueue.push(task);
45
+ if (!isTaskRunnerScheduled) {
46
+ isTaskRunnerScheduled = true;
47
+ if ("requestIdleCallback" in window) {
48
+ window.requestIdleCallback(processTasks, { timeout: 1000 });
49
+ } else {
50
+ setTimeout(processTasks, 50);
51
+ }
52
+ }
53
+ } // --- Scheduler End ---
@@ -0,0 +1,116 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>
4
+ [RFC-0210] Feature-video runtime. Lazily upgrades native <video controls> elements marked
5
+ [data-video-player] into a branded Plyr player, attaching hls.js for adaptive HLS playback on
6
+ browsers without native HLS. Follows the RFC-0175 click-to-load / in-viewport posture: nothing
7
+ is imported until a feature video is near the viewport, so pages without a feature video (and
8
+ the above-the-fold paint) ship zero player bytes. Resolves and records the playback mode
9
+ (file|stream) + impl (native|hlsjs|progressive) on the element. Degrades to the native controls
10
+ if Plyr/hls.js fail to load (progressive enhancement).
11
+ </purpose>
12
+ <non-goals>
13
+ <item>Do not touch ambient/background <video> — those are native (handled by live-photos).</item>
14
+ </non-goals>
15
+ </MODULE_CONTRACT>
16
+ <CHANGE_SUMMARY>
17
+ <item>RFC-0210: introduced the lazy feature-video player runtime.</item>
18
+ </CHANGE_SUMMARY>
19
+ */
20
+
21
+ import "plyr/dist/plyr.css";
22
+
23
+ export interface VideoPlayersOptions {
24
+ prefersReducedMotion?: boolean;
25
+ }
26
+
27
+ function nativeHlsSupported(video: HTMLVideoElement): boolean {
28
+ return video.canPlayType("application/vnd.apple.mpegurl") !== "";
29
+ }
30
+
31
+ async function upgrade(video: HTMLVideoElement): Promise<void> {
32
+ if (video.dataset.videoPlayerReady === "true") return;
33
+ video.dataset.videoPlayerReady = "true";
34
+
35
+ const hlsUrl = video.dataset.hls;
36
+ let mode: "file" | "stream" = "file";
37
+ let impl: "native" | "hlsjs" | "progressive" = "progressive";
38
+ let hlsInstance: { destroy: () => void } | null = null;
39
+
40
+ if (hlsUrl) {
41
+ if (nativeHlsSupported(video)) {
42
+ // Safari/iOS: native HLS — make the manifest the preferred source.
43
+ const source = document.createElement("source");
44
+ source.src = hlsUrl;
45
+ source.type = "application/vnd.apple.mpegurl";
46
+ video.insertBefore(source, video.firstChild);
47
+ video.load();
48
+ mode = "stream";
49
+ impl = "native";
50
+ } else {
51
+ try {
52
+ const { default: Hls } = await import("hls.js/light");
53
+ if (Hls.isSupported()) {
54
+ const hls = new Hls({ enableWorker: true });
55
+ hls.loadSource(hlsUrl);
56
+ hls.attachMedia(video);
57
+ hlsInstance = hls;
58
+ mode = "stream";
59
+ impl = "hlsjs";
60
+ }
61
+ } catch {
62
+ /* hls.js unavailable — fall through to progressive MP4 sources */
63
+ }
64
+ }
65
+ }
66
+
67
+ video.dataset.playbackMode = mode;
68
+ video.dataset.playbackImpl = impl;
69
+
70
+ // Brand the UI with Plyr (the native controls remain the fallback if this fails).
71
+ try {
72
+ const { default: Plyr } = await import("plyr");
73
+ const player = new Plyr(video, {
74
+ controls: [
75
+ "play-large",
76
+ "play",
77
+ "progress",
78
+ "current-time",
79
+ "mute",
80
+ "volume",
81
+ "captions",
82
+ "fullscreen",
83
+ ],
84
+ });
85
+ // Keep hls.js bound across Plyr's internal media swaps.
86
+ void player;
87
+ void hlsInstance;
88
+ } catch {
89
+ /* Plyr unavailable — native controls already present */
90
+ }
91
+ }
92
+
93
+ export async function initVideoPlayers(_options: VideoPlayersOptions = {}): Promise<void> {
94
+ const videos = Array.from(
95
+ document.querySelectorAll<HTMLVideoElement>("video[data-video-player]"),
96
+ );
97
+ if (videos.length === 0) return;
98
+
99
+ if (!("IntersectionObserver" in window)) {
100
+ for (const v of videos) await upgrade(v);
101
+ return;
102
+ }
103
+
104
+ const observer = new IntersectionObserver(
105
+ (entries, obs) => {
106
+ for (const entry of entries) {
107
+ if (!entry.isIntersecting) continue;
108
+ const video = entry.target as HTMLVideoElement;
109
+ obs.unobserve(video);
110
+ void upgrade(video);
111
+ }
112
+ },
113
+ { rootMargin: "200px" },
114
+ );
115
+ for (const v of videos) observer.observe(v);
116
+ }
@@ -0,0 +1,140 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>
4
+ RFC-0051 ai.txt generation. Pure function buildAiTxt produces the
5
+ machine-readable AI policy file from a structured AiPolicy config.
6
+ </purpose>
7
+ <non-goals>
8
+ <item>Do not read content files or validate input — the caller is responsible.</item>
9
+ <item>Do not manage default policy fallback — caller decides skip vs fallback.</item>
10
+ </non-goals>
11
+ </MODULE_CONTRACT>
12
+ <CHANGE_SUMMARY>
13
+ <item>RFC-0051: Initial implementation.</item>
14
+ </CHANGE_SUMMARY>
15
+ */
16
+
17
+ export interface AiProviderOverride {
18
+ name: string;
19
+ policy: "allow" | "disallow" | "limited";
20
+ training?: "allow" | "disallow";
21
+ usage?: string[];
22
+ commercial?: "yes" | "no";
23
+ attribution?: "required" | "optional" | "none";
24
+ license?: string;
25
+ contact?: string;
26
+ url?: string;
27
+ }
28
+
29
+ export interface AiPolicy {
30
+ policy: "allow" | "disallow" | "limited";
31
+ training?: "allow" | "disallow";
32
+ usage?: string[];
33
+ commercial?: "yes" | "no";
34
+ attribution?: "required" | "optional" | "none";
35
+ license?: string;
36
+ contact?: string;
37
+ url?: string;
38
+ version?: string;
39
+ updated?: string;
40
+ providers?: AiProviderOverride[];
41
+ }
42
+
43
+ function formatKeyValue(key: string, value: string | undefined): string | null {
44
+ if (value === undefined || value === null) return null;
45
+ return `${key}: ${value}`;
46
+ }
47
+
48
+ function _formatList(key: string, values: string[] | undefined): string | null {
49
+ if (!values || values.length === 0) return null;
50
+ return `${key}: ${values.join(", ")}`;
51
+ }
52
+
53
+ export function buildAiTxt(policy: AiPolicy, siteUrl: string): string {
54
+ const lines: string[] = [];
55
+
56
+ const headerComment = siteUrl
57
+ ? `# ai.txt for ${siteUrl.replace(/^https?:\/\//, "")}`
58
+ : "# ai.txt";
59
+ lines.push(headerComment);
60
+ lines.push("# AI training and usage policy");
61
+ if (policy.url) lines.push(`# See: ${policy.url}`);
62
+ if (policy.contact) lines.push(`# Contact: ${policy.contact}`);
63
+ lines.push("");
64
+
65
+ const version = policy.version ?? "0.1";
66
+ const updated = policy.updated ?? new Date().toISOString().slice(0, 10);
67
+ lines.push(`version: ${version}`);
68
+ lines.push(`updated: ${updated}`);
69
+ lines.push("");
70
+
71
+ lines.push("# Default policy for AI systems");
72
+ lines.push(`policy: ${policy.policy}`);
73
+
74
+ const optionalGlobalFields: Array<[string, string | undefined]> = [
75
+ ["license", policy.license],
76
+ ["url", policy.url],
77
+ ["contact", policy.contact],
78
+ ];
79
+
80
+ const pushLine = (key: string, val: string | undefined | string[]) => {
81
+ if (Array.isArray(val) && val.length > 0) {
82
+ lines.push(`${key}: ${val.join(", ")}`);
83
+ } else if (typeof val === "string" && val.length > 0) {
84
+ lines.push(`${key}: ${val}`);
85
+ }
86
+ };
87
+
88
+ pushLine("training", policy.training);
89
+ pushLine("usage", policy.usage);
90
+ pushLine("commercial", policy.commercial);
91
+ pushLine("attribution", policy.attribution);
92
+
93
+ for (const [key, val] of optionalGlobalFields) {
94
+ const line = formatKeyValue(key, val);
95
+ if (line) lines.push(line);
96
+ }
97
+
98
+ const unknownKeys = new Set(Object.keys(policy));
99
+ const knownKeys = new Set([
100
+ "policy",
101
+ "training",
102
+ "usage",
103
+ "commercial",
104
+ "attribution",
105
+ "license",
106
+ "contact",
107
+ "url",
108
+ "version",
109
+ "updated",
110
+ "providers",
111
+ ]);
112
+ for (const key of unknownKeys) {
113
+ if (!knownKeys.has(key)) {
114
+ const val = (policy as unknown as Record<string, unknown>)[key];
115
+ if (typeof val === "string" && val.length > 0) {
116
+ lines.push(`${key}: ${val}`);
117
+ }
118
+ }
119
+ }
120
+
121
+ if (policy.providers && policy.providers.length > 0) {
122
+ lines.push("");
123
+ for (const provider of policy.providers) {
124
+ lines.push(`[${provider.name}]`);
125
+ lines.push(`policy: ${provider.policy}`);
126
+ if (provider.training) lines.push(`training: ${provider.training}`);
127
+ if (provider.usage && provider.usage.length > 0) {
128
+ lines.push(`usage: ${provider.usage.join(", ")}`);
129
+ }
130
+ if (provider.commercial) lines.push(`commercial: ${provider.commercial}`);
131
+ if (provider.attribution) lines.push(`attribution: ${provider.attribution}`);
132
+ if (provider.license) lines.push(`license: ${provider.license}`);
133
+ if (provider.contact) lines.push(`contact: ${provider.contact}`);
134
+ if (provider.url) lines.push(`url: ${provider.url}`);
135
+ lines.push("");
136
+ }
137
+ }
138
+
139
+ return lines.join("\n").trimEnd() + "\n";
140
+ }
@@ -0,0 +1,52 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>RFC-0208: block text extraction types and registry. Declarative extractors map block-based page content into semantic text for markdown twins.</purpose>
4
+ <non-goals>
5
+ <item>Do not contain extractor implementations — those live in block-extractors/.</item>
6
+ </non-goals>
7
+ </MODULE_CONTRACT>
8
+ <CHANGE_SUMMARY>
9
+ <item>RFC-0208: introduced block extraction layer for comprehensive markdown twins.</item>
10
+ </CHANGE_SUMMARY>
11
+ */
12
+
13
+ export interface ExtractionContext {
14
+ pageId: string;
15
+ lang: string;
16
+ siteUrl: string;
17
+ }
18
+
19
+ export interface ExtractedBlockContent {
20
+ heading?: string;
21
+ lead?: string;
22
+ body?: string;
23
+ items?: Array<{ title: string; description?: string }>;
24
+ sourceBlockId?: string;
25
+ }
26
+
27
+ export interface BlockTextExtractor<T = unknown> {
28
+ blockType: string;
29
+ extract(props: T, ctx: ExtractionContext): ExtractedBlockContent;
30
+ }
31
+
32
+ export class BlockExtractorRegistry {
33
+ private extractors = new Map<string, BlockTextExtractor>();
34
+
35
+ register<T>(extractor: BlockTextExtractor<T>): void {
36
+ this.extractors.set(extractor.blockType, extractor as BlockTextExtractor<unknown>);
37
+ }
38
+
39
+ get(blockType: string): BlockTextExtractor | undefined {
40
+ return this.extractors.get(blockType);
41
+ }
42
+
43
+ has(blockType: string): boolean {
44
+ return this.extractors.has(blockType);
45
+ }
46
+
47
+ listTypes(): string[] {
48
+ return Array.from(this.extractors.keys());
49
+ }
50
+ }
51
+
52
+ export const BLOCK_EXTRACTORS = new BlockExtractorRegistry();