openvibers/openvibe.design Commits
/developers has a Markdown twin; llms.txt links it (#150)
Changes
@@@ -11,7 +11,8 @@const express = require('express');const agentLayer = require('openvibe-shared/agent-layer');--const TWIN_PATH_RE = /^\/(?:arena|brand|components|kit|loading|look|motion|studio|tokens|t\/[A-Za-z0-9_-]+)?$/;++// /developers (the theme API) is on the same page router: an agent's most useful page here (11-03).++const TWIN_PATH_RE = /^\/(?:arena|brand|components|developers|kit|loading|look|motion|studio|tokens|t\/[A-Za-z0-9_-]+)?$/;/** A response the page code can write to; the first body written is the page's HTML. */function mockRes() {@@@ -92,7 +92,7 @@ function createDiscoveryRoutes(ctx) {{ title: 'Loading', url: abs('/loading'), note: 'how OpenVibe waits: placeholders shaped like the content (kit.skeleton: card, row, tile, chip, line, chat, stat), the mark at work instead of a spinner (OpenVibeLoading), the navbar while a page moves (OpenVibeNavbar.busy), and the rules' },{ title: 'The OpenVibe mark', url: abs('/brand'), note: 'the logo, its states and motion, colours, the brand face, SVG files and code (openvibe-shared/mark, ov-mark.js)' },{ title: 'The Design Arena', url: abs('/arena'), note: 'one prompt, three AI designers, blind votes and an Elo leaderboard' },-- { title: 'For developers', url: abs('/developers'), note: 'the theme API proxy', html: true },++ { title: 'For developers', url: abs('/developers'), note: 'the theme API proxy' },] },{ title: 'Themes', links: list.filter((t) => t && t.slug).slice(0, 100).map((t) => ({ title: String(t.name || t.slug), url: abs(`/t/${encodeURIComponent(String(t.slug))}`), note: `${t.mode ? String(t.mode) : 'theme'}${t.description ? ` — ${String(t.description)}` : ''}` })) },// The data an agent came for is a main section, not something to skip.@@@ -8,7 +8,7 @@ const { boot } = require('./helpers/boot');const { TWIN_PATH_RE } = require('../server/agent-twins');// Public pages from the sitemap that render without data.--const PAGES = ['/', '/brand', '/components', '/tokens', '/motion', '/kit'];++const PAGES = ['/', '/brand', '/components', '/tokens', '/motion', '/kit', '/developers'];(async () => {const t = await boot();
@@ -11,7 +11,8 @@
@@ -11,7 +11,8 @@
const express = require('express');
const express = require('express');
const agentLayer = require('openvibe-shared/agent-layer');
const agentLayer = require('openvibe-shared/agent-layer');
-const TWIN_PATH_RE = /^\/(?:arena|brand|components|kit|loading|look|motion|studio|tokens|t\/[A-Za-z0-9_-]+)?$/;
+// /developers (the theme API) is on the same page router: an agent's most useful page here (11-03).
+const TWIN_PATH_RE = /^\/(?:arena|brand|components|developers|kit|loading|look|motion|studio|tokens|t\/[A-Za-z0-9_-]+)?$/;
/** A response the page code can write to; the first body written is the page's HTML. */
/** A response the page code can write to; the first body written is the page's HTML. */
function mockRes() {
function mockRes() {
@@ -92,7 +92,7 @@ function createDiscoveryRoutes(ctx) {
@@ -92,7 +92,7 @@ function createDiscoveryRoutes(ctx) {
{ title: 'Loading', url: abs('/loading'), note: 'how OpenVibe waits: placeholders shaped like the content (kit.skeleton: card, row, tile, chip, line, chat, stat), the mark at work instead of a spinner (OpenVibeLoading), the navbar while a page moves (OpenVibeNavbar.busy), and the rules' },
{ title: 'Loading', url: abs('/loading'), note: 'how OpenVibe waits: placeholders shaped like the content (kit.skeleton: card, row, tile, chip, line, chat, stat), the mark at work instead of a spinner (OpenVibeLoading), the navbar while a page moves (OpenVibeNavbar.busy), and the rules' },
{ title: 'The OpenVibe mark', url: abs('/brand'), note: 'the logo, its states and motion, colours, the brand face, SVG files and code (openvibe-shared/mark, ov-mark.js)' },
{ title: 'The OpenVibe mark', url: abs('/brand'), note: 'the logo, its states and motion, colours, the brand face, SVG files and code (openvibe-shared/mark, ov-mark.js)' },
{ title: 'The Design Arena', url: abs('/arena'), note: 'one prompt, three AI designers, blind votes and an Elo leaderboard' },
{ title: 'The Design Arena', url: abs('/arena'), note: 'one prompt, three AI designers, blind votes and an Elo leaderboard' },
- { title: 'For developers', url: abs('/developers'), note: 'the theme API proxy', html: true },
+ { title: 'For developers', url: abs('/developers'), note: 'the theme API proxy' },
] },
] },
{ title: 'Themes', links: list.filter((t) => t && t.slug).slice(0, 100).map((t) => ({ title: String(t.name || t.slug), url: abs(`/t/${encodeURIComponent(String(t.slug))}`), note: `${t.mode ? String(t.mode) : 'theme'}${t.description ? ` — ${String(t.description)}` : ''}` })) },
{ title: 'Themes', links: list.filter((t) => t && t.slug).slice(0, 100).map((t) => ({ title: String(t.name || t.slug), url: abs(`/t/${encodeURIComponent(String(t.slug))}`), note: `${t.mode ? String(t.mode) : 'theme'}${t.description ? ` — ${String(t.description)}` : ''}` })) },
// The data an agent came for is a main section, not something to skip.
// The data an agent came for is a main section, not something to skip.
@@ -8,7 +8,7 @@ const { boot } = require('./helpers/boot');
@@ -8,7 +8,7 @@ const { boot } = require('./helpers/boot');
const { TWIN_PATH_RE } = require('../server/agent-twins');
const { TWIN_PATH_RE } = require('../server/agent-twins');
// Public pages from the sitemap that render without data.
// Public pages from the sitemap that render without data.
-const PAGES = ['/', '/brand', '/components', '/tokens', '/motion', '/kit'];
+const PAGES = ['/', '/brand', '/components', '/tokens', '/motion', '/kit', '/developers'];
(async () => {
(async () => {
const t = await boot();
const t = await boot();