Commits
-
T11 lane D step 1 — openvibe-shared/shell, the server-rendered page… (#12)OpenVibers · 3 Oct 2026
a567e37 -
Bump openvibe-shared to 2.5.0 and date the changelog entry (#9)OpenVibers · 2 Oct 2026
b995404 -
Add a starter site scaffold and create-site command (#6)OpenVibers · 2 Oct 2026
c76302d -
Add hashed asset builder and responsive picture variants (#4)OpenVibers · 2 Oct 2026
4cfa2a3 -
Add the assets helper for hashed URLs and responsive pictures (#3)OpenVibers · 2 Oct 2026
705a46c -
Bump openvibe-shared to 2.4.0 and date the changelog entry (#2)OpenVibers · 2 Oct 2026
98c35a8 -
Shared 2.3.1: /shared/showcase.css, the showcase sections and the ring icons' CSS as one cacheable stylesheet (files.js STYLES, served as text/css; generated by scripts/build-styles.js and checked by the showcase test), so a product home links it instead of inlining it. 47/47.OpenVibers · 29 Sept 2026
c2238d0 -
Shared 2.3.0: openvibe-shared/showcase (plan T11, D92), the sections a product home is built from — hero, features, steps, code, demo, compare, pricing, limits (pricing that equals the API's limits, citing its source), stories, cta — server-rendered plain HTML with inline CSS on the theme tokens; every string escaped (only an html field passes markup), empty sections render nothing, heading ids from titles. test/showcase.test.js; 47/47.OpenVibers · 29 Sept 2026
742682a -
Shared 2.2.0 (plan T11): boost.js starts itself from its script tag (data-main, data-prefix, data-exclude; OVBoost.controller) and carries the new page's body class; navbar.js follows a boost swap (re-renders for active links and a sign-in that returns to the new page, records the new page in the person's history). boost-chrome.test.js runs the auto-start path and checks the body class. 46/46.OpenVibers · 29 Sept 2026
c34086d -
Shared 2.1.0 (plan T11): boost.js — smooth same-site page moves for a server-rendered site (prefetch on intent, styles first, <main> swapped in place with the shared transition, head tags, history and scroll, focus; any doubt is a normal load), tested in real Chrome; openvibe-shared/cache-policy (hashed asset immutable, HTML stale-while-revalidate: one rule, serve.js uses it); openvibe-shared/indexnow (deduped, own-host https pings, a debounced batch, never throws, no key no request). npm test 46/46.OpenVibers · 29 Sept 2026
6a8cd5d -
Shared 2.0.0: X-Internal-Key is gone from the shared package (plan T2). internalApiAuth, OpenVibeAuthClient#verifyTokenInternal (Network's deleted /internal/verify-token) and #getUserProfile (a route Network never had) are removed, and the deprecated openvibe-shared/chrome-ssr alias with them (use openvibe-shared/frame). Nothing in the estate used any of it. A test asserts the helpers stay gone. npm test 42/42.OpenVibers · 29 Sept 2026
47719cc -
Shared 1.30.1: the first in-site move animates (first page = first enter() at route generation ≤ 1), route-transition.js preloads after load, the loading line lives outside the section (re-renders cannot remove it), requested by path so the versions map hashes it. Measured on Live at 400 ms latency: bar, 'Loading Content…' → 'starting up', fade-in, never unstyled. npm test 42/42.OpenVibers · 29 Sept 2026
6ffa241 -
Shared 1.30.0: pages never show unstyled (web-runtime inserts a fragment once its feature's and dependencies' stylesheets have loaded, all started together), rt.enter(section, work, { label }) hides a page until its route is ready, and route-transition.js (fetched on the first move) adds the top progress bar, a 'Loading …' line with the phase, and an opacity-only fade-in. Runtime docs moved to the README (6.2 KB brotli). npm test 42/42.OpenVibers · 29 Sept 2026
fabec42 -
Shared 1.29.2: navbar dropdowns (Live's Go Live → Dashboard) are no longer clipped by the sideways-scrolling links row: the menu is fixed-positioned under its link on hover, focus or tap, offset by a filtered bar's box. Usage notes moved from navbar.js to the README (navbar 28.7 KB brotli, budget 29). npm test 42/42.OpenVibers · 29 Sept 2026
e2c1bdf -
Shared 1.29.1: themes repaint the canvas through the variables (a page's own theme switcher changes the background too), save() applies the theme it saves, and themes without --on-accent get readable button text derived by WCAG luminance (near-black on bright accents); onColor(hex) exported. Navbar brand compact: 6px mark gap, 2px padding, side padding clamp(8px,1.6vw,16px). npm test 42/42.OpenVibers · 29 Sept 2026
ca7d235 -
Shared 1.29.0: openvibe-shared/analytics/pg, request analytics on PostgreSQL (AnalyticsTrackerPg with the same tables and dashboard shapes, analyticsSchema() for migrations, batched 30-day retention). The request path never waits for the database; the day's salt is shared across processes so uniques stay right; no address reaches the database. npm test 42/42.OpenVibers · 28 Sept 2026
1e4bbc3 -
Shared 1.28.1: the account panel's sections keep their height (the accounts block no longer collapses into a sliver with its own scrollbar on phones) and its rows match the menu rows; the OpenVibe.Codes mark at rest shows its V (the looping draw animation was paused at its first, undrawn frame); phones no longer reserve 84-96 px of empty space under the footer (--ov-footer-clearance opts in). npm test 41/41.OpenVibers · 28 Sept 2026
8c5df1b -
Shared 1.28.0: openvibe-shared/config on PostgreSQL. Given an openvibe-sdk/db handle, createConfigStore uses config-pg.js, the same store on the async handle (immutable revisions, atomic activation, last-known-good restored when onActivate fails, redacted secrets with a per-namespace fingerprint key, legacy import) and returns a promise of the store; get() and revision() stay in memory, the rest is async. configSchema() is the DDL for the service's migrations. adminRoutes awaits either kind of store; the better-sqlite3 path is unchanged. test/config-pg.test.js runs every scenario of config.test.js on PGlite (openvibe-sdk v0.20.4 as a dev dependency; its made-up secrets are allowlisted like the original's). npm test 41/41.OpenVibers · 28 Sept 2026
116e07a -
Shared 1.27.0: openvibe-shared/express-async. Express 4 ignores what a handler returns, so a promise an async handler rejects (a database error, a thrown problem) became an unhandled rejection, and Node 22 ends the process on one; the move to PostgreSQL made most handlers async (nine services had 5-41 such routes, confirmed to exit). routeAsyncErrors(app) patches the app's own Express 4 Layer once so the rejection reaches next(err) and the service's error handler answers, as a synchronous throw always did; error handlers too; a no-op on Express 5. instrument() calls it, so every service is covered by a pin bump. npm test 40/40.OpenVibers · 28 Sept 2026
cded2bc -
Shared 1.26.0: async gauges. A gauge's collect() may return a promise (a database read, now that services are on PostgreSQL, ADR-035). The /metrics handler awaits every async collect together through the new registry.metricsAsync({ timeoutMs = 2000 }); one that rejects or runs past its budget is left out of that scrape, never reported stale, as a throwing one already was. The synchronous registry.metrics() is unchanged and leaves an async gauge out. The handler is an async function; its callers need no change. npm test 39/39.OpenVibers · 28 Sept 2026
49ce9d6 -
Shared 1.25.0: openvibe-shared/test-runner, no fake green in npm test (roadmap WS-Q task 7). Every service carried its own test/run.js, and each counted a test file that exited 0 as passed, including one that printed "…: skipped (no ffmpeg)" and checked nothing, so "150/150 test files passed" could hide skipped work. The runner is now one module, main({ dir, timeoutMs, pad, hide, env }) (run() returns the results): the copies' behaviour (each *.test.js in its own process, a few at a time, NODE_ENV=test, a timeout per file, name filters, the last 40 lines of a failure minus hide lines), plus skips: a test prints "<label>: skipped (<why>)" for what it could not run (the line OpenVibe.Host's acceptance runner already reads), and that file is listed with ○ and its reasons and not counted as passed; the summary reads "148/150 test files passed, 2 skipped (…)", and only a run with nothing skipped says N/N. Skips alone exit 0; --strict or OV_TEST_STRICT=1 makes them fail. Exported as ./test-runner; this package's test/run.js uses it; test/test-runner.test.js covers pass, skip, partial skip, failure, hidden lines, filters and strict. README and CHANGELOG describe it. npm test (Node 22) 39/39.OpenVibers · 28 Sept 2026
919c108 -
Shared 1.24.0: no fake green in readiness (roadmap WS-Q task 7). ready.js knew only ok and fail, so a check whose feature was not configured had to claim ok (Network's Discord bot, Media's events outbox and News's source pull did, as production's /api/ready shows) or fail and turn the service yellow for a setting. A check now returns skip(reason, detail?) (exported) or { skipped: reason }: it reports status skipped with the reason, never ok, and is listed in the body's new skipped array. A skipped optional check leaves a service whose other checks passed ready; a skipped required check is also degraded (yellow, still HTTP 200: nothing failed); and a service is ready only when at least one check really passed, so one with no checks or every check skipped is degraded (before: ready). test/ready.test.js covers each case; README and CHANGELOG describe it. npm test (Node 22) 38/38.OpenVibers · 28 Sept 2026
48b7443 -
v1.23.1: two release-watch fixes found by the release-lifecycle acceptance scenarios (D46, roadmap WS-P task 16; OpenVibe.Host scripts/release-acceptance.js), and tests for scenarios 4, 9 and 14.OpenVibers · 27 Sept 2026
23d41bf -
v1.23.0: web runtime, a site's feature loader and route lifecycle (roadmap WS-P task 6). New browser file web-runtime.js (OVWebRuntime.create; files.js, export openvibe-shared/web-runtime; 6.1 KB brotli, budget 6.5 KB): OpenVibe.Live's public/js/ov-loader.js made shareable. It keeps the feature registry and routes, once-only scripts and stylesheets (the server's tags adopted), versioned URLs, fragments, route generations, scopes, intent and idle prefetch, stubs and the route retry box. New: transactional asset groups (a feature commits only when every script loaded; a failure withdraws that attempt's stylesheets unless another feature wants them and removes the failed tag; a retry fetches only what is missing, nothing runs twice); scopes that refuse and count late registrations, scope.fetch on the route's signal, child scopes, held() counts, fired timeouts released; a prefetch budget (count, and bytes where sizes are known); diagnostics() and leaks() (duplicate tags, failed and rolled-back assets, late registrations, what the route holds). showRouteError builds DOM; another origin's assets are keyed by origin and path. Tests: linkedom (tags load or fail on cue) and headless Chrome (a slow script still in order, a real 404 rolls back and the retry completes, a route's interval stops and its fetch aborts).OpenVibers · 27 Sept 2026
1dfdc41 -
Pins: openvibe-contracts -> 0.61.0 (network.notification.created@1, identity.realtime-ticket-claims@1, network.realtime-ticket-result@1)OpenVibers · 26 Sept 2026
dbf9d39 -
v1.22.0: the notification bell in realtime, off by default (roadmap WS-E task 3, WS-F task 1; openvibe-contracts 0.61.0, ADR-005 amendment 2). New browser file notification-live.js (OVNotificationLive, 2.4 KB brotli, budget 3 KB): a realtime ticket from Network (POST /api/v1/realtime/ticket, Bearer or the openvibe.network cookie) for every (re)connect, then Events' /realtime/stream?topics=network.notification.*&ticket= without credentials, resuming with last_event_id; only the ticket's person's events count; gaps reported; errors close and back off from 2 s with jitter, ten in a row stop it until online; hidden 5 min closes, shown resumes; CSP refusal, 401/403 and 503 stop it. notification-ui.js (budget 13 KB) loads it from its own directory with init({ realtime: true }) (navbar: notificationsRealtime: true): an event re-reads the count once per burst (and again after a poll in flight), a gap also reloads open lists, the 15 s poll runs every 2 min while the stream is open; setToken() restarts it; realtimeState(). files.js and exports list it; browser-harness exports openPage. Tests: linkedom (subscribe, resume from the cursor, gap -> refetch, CSP-blocked -> polling, guessed topic yields nothing) and headless Chrome with a real EventSource (drop and resume with nothing lost or repeated, retention gap, another person's event ignored)OpenVibers · 26 Sept 2026
3282427 -
v1.21.0: browser harness checkUnreachable (ADR-024, roadmap WS-E task 1): openPage({ block }) fails every request matching a pattern, and checkUnreachable(url) reports whether a page still paints (200, settled, text, a --accent token, a background) with openvibe.network unreachable; blocked requests are not page errors. Tested in headless ChromeOpenVibers · 26 Sept 2026
749cbcf -
v1.20.0: release manifest 1.2.0 (roadmap WS-P task 7, openvibe-contracts 0.60.0): createRelease serves client_generation, min_client_generation (env MIN_CLIENT_GENERATION) and shell { version, components }; the meta tag carries data-generation; a tab below the minimum generation reloads when safe (required) and a changed shell never goes in place (it prompts). Contracts devDependency 0.60.0OpenVibers · 26 Sept 2026
36ac2da -
v1.19.0: the update matrix, complete (roadmap WS-P task 8): release-update sends ov:content-dispose before a region is replaced so a widget inside drops its listeners and timers (ov:content-updated follows to mount it again); tests cover every row (style swap and ov:styles-updated, revision-aware content with scroll kept, widget disposal, busy deferral, prompt, security minimum); the README lists the matrixOpenVibers · 26 Sept 2026
d8693c9 -
v1.18.0: update telemetry (roadmap WS-P task 14): release-watch counts the update prompt (prompted: optional, required, window, contract) and beats every 5 minutes with a random in-memory tab id and its release, saying ended on pagehide; the collector keeps tabs heard from in 12 minutes as release_client_sessions{generation=current|older} against the release the process serves. release-watch stays under its 5 KB brotli budget (4.96 KB) by shortening commentsOpenVibers · 26 Sept 2026
e1f7441