OpenVibe.Shared releases

Release 2.5.0

2 Oct 2026 · pinned package [email protected]

2.5.0

  • seo.feedXml(feed, { format }) takes items as { title, link, guid?, description?, content?, author?, published, updated? } and the feed's language and selfUrl. RSS adds <language>, an atom:link rel="self" and a lastBuildDate that is always present. Atom adds link rel="alternate"/rel="self", xml:lang, <content type="html"> and an <updated> that is always present. Without updated, both use the newest item date, or now when there are no items. Text is escaped with esc, so ' becomes &#39;. The 2.4.0 url, id and summary still work.
  • seo.llmsFull takes base and sections of pages: [{ title, url, text | html }]: each page renders as ### title, URL: … and its full text (HTML stripped), in input order, and maxBytes ends the file with a (truncated: N more pages at <base>/llms.txt) line. The 2.4.0 { url, body } sections render unchanged. seo.pageSummary now converts to an HTML string — <meta name="ai-summary">, WebPage JSON-LD and, with string facts, a <noscript><section data-ai-summary> block — and has .head/.body; its meta, jsonLd and html are unchanged. templates/site serves /llms-full.txt and puts the summary in its head.
  • perf-budget measures Core Web Vitals (plan T11). measure({ browser }) opens the page in Chrome through browser-harness after the byte pass, clicks once, and adds cwv: { lcpMs, inpMs, cls }. check() accepts lcpMs, inpMs and cls budgets and throws when they are used without cwv; format() prints a cwv: line. Without browser, measurement is unchanged and needs no Chrome.
  • The asset pipeline adds hashAsset(bytes), generated AVIF and WebP srcsets from picture({ src, widths, ... }), and openvibe-build-assets to copy files to hashed names with a manifest.json lookup. The builder does not transcode images.
  • openvibe-shared/assets (plan T11): content-addressed asset URLs and responsive <picture> markup for a product page. hash(bytes) is the estate's sha256 truncated to 12 hex; url(src, hash) appends ?v=, replaces an old one and leaves the path unchanged when there is no hash; srcset(entries) builds a srcset; picture({ src, hash?, alt, width, height, sizes, sources }) emits AVIF before WebP before the fallback <img> (any other type ranks after WebP), renders a plain <img> when there is nothing to choose between, and renders nothing without a src. Formats come from the caller: this package does not transcode images, so it only emits the AVIF/WebP variants a site's own build produced.

Rules90 Assets are addressed by their content, so people always get the current one.

All releases