openvibers/openvibe.design Commits
/llms-full.txt (SEO-33): the site in full (#145)
Changes
@@@ -75,9 +75,8 @@ function createDiscoveryRoutes(ctx) {+ seo.robotsTxt({ sitemaps: [abs('/sitemap.xml')], disallow: DISALLOW }));});-- r.get('/llms.txt', async (_req, res) => {-- const list = await themes();-- res.type('text/plain').set('Cache-Control', TEXT).send(seo.llmsTxt({++ // The site as llms.txt describes it, shared by /llms.txt and /llms-full.txt (SEO-33).++ const llmsSite = (list) => ({name: SITE_NAME,summary: DESCRIPTION,details: 'Theme selection stays in OpenVibe.Network (its theme API); this service signs the person in and proxies their calls. The pages here are server-rendered and readable without JavaScript, and the theme catalogue is public.',@@@ -106,6 +105,20 @@ function createDiscoveryRoutes(ctx) {{ title: 'OpenVibe.Network', url: 'https://openvibe.network', note: 'accounts and the theme API this service proxies' },] },],++ });++ r.get('/llms.txt', async (_req, res) => {++ const list = await themes();++ res.type('text/plain').set('Cache-Control', TEXT).send(seo.llmsTxt(llmsSite(list)));++ });++ // The same, in full (SEO-33): what the site is, then every page llms.txt lists with what it holds.++ r.get('/llms-full.txt', async (_req, res) => {++ const d = llmsSite(await themes());++ res.type('text/plain').set('Cache-Control', TEXT).send(seo.llmsFull({++ site: d.name, summary: d.summary, base: abs('/'),++ sections: [++ { title: 'About', pages: [{ title: d.name, url: abs('/'), text: [d.summary, d.details].filter(Boolean).join('\n\n') }] },++ ...(d.sections || []).map((x) => ({ title: x.title, pages: (x.links || []).map((l) => ({ title: l.title, url: l.url, text: l.note || '' })) })),++ ],}));});@@@ -225,6 +225,15 @@ const form = (fields) => ({ body: new URLSearchParams(fields).toString(), headerassert.equal((await t.get('/api/v1/glyphs/drafts?status=nope', { as: boss })).status, 422);});++ await check('llms-full.txt (SEO-33): the site in full, from the same descriptor as llms.txt', async () => {++ const r = await t.get('/llms-full.txt');++ assert.strictEqual(r.status, 200);++ assert.match(r.headers.get('content-type') || '', /^text\/plain/);++ assert.ok(r.text.startsWith('# OpenVibe.Design'), r.text.slice(0, 60));++ assert.ok(r.text.length > 500, `${r.text.length} characters`);++ assert.match(r.text, /## About\n\n### /);++ });++await check('it is in the navbar, the sitemap and llms.txt', async () => {assert.ok((await t.get('/sitemap.xml')).text.includes('/icons</loc>'), 'sitemap');assert.ok((await t.get('/llms.txt')).text.includes('/icons'), 'llms.txt');
@@ -75,9 +75,8 @@ function createDiscoveryRoutes(ctx) {
@@ -75,9 +75,8 @@ function createDiscoveryRoutes(ctx) {
+ seo.robotsTxt({ sitemaps: [abs('/sitemap.xml')], disallow: DISALLOW }));
+ seo.robotsTxt({ sitemaps: [abs('/sitemap.xml')], disallow: DISALLOW }));
});
});
- r.get('/llms.txt', async (_req, res) => {
- const list = await themes();
- res.type('text/plain').set('Cache-Control', TEXT).send(seo.llmsTxt({
+ // The site as llms.txt describes it, shared by /llms.txt and /llms-full.txt (SEO-33).
+ const llmsSite = (list) => ({
name: SITE_NAME,
name: SITE_NAME,
summary: DESCRIPTION,
summary: DESCRIPTION,
details: 'Theme selection stays in OpenVibe.Network (its theme API); this service signs the person in and proxies their calls. The pages here are server-rendered and readable without JavaScript, and the theme catalogue is public.',
details: 'Theme selection stays in OpenVibe.Network (its theme API); this service signs the person in and proxies their calls. The pages here are server-rendered and readable without JavaScript, and the theme catalogue is public.',
@@ -106,6 +105,20 @@ function createDiscoveryRoutes(ctx) {
@@ -106,6 +105,20 @@ function createDiscoveryRoutes(ctx) {
{ title: 'OpenVibe.Network', url: 'https://openvibe.network', note: 'accounts and the theme API this service proxies' },
{ title: 'OpenVibe.Network', url: 'https://openvibe.network', note: 'accounts and the theme API this service proxies' },
] },
] },
],
],
+ });
+ r.get('/llms.txt', async (_req, res) => {
+ const list = await themes();
+ res.type('text/plain').set('Cache-Control', TEXT).send(seo.llmsTxt(llmsSite(list)));
+ });
+ // The same, in full (SEO-33): what the site is, then every page llms.txt lists with what it holds.
+ r.get('/llms-full.txt', async (_req, res) => {
+ const d = llmsSite(await themes());
+ res.type('text/plain').set('Cache-Control', TEXT).send(seo.llmsFull({
+ site: d.name, summary: d.summary, base: abs('/'),
+ sections: [
+ { title: 'About', pages: [{ title: d.name, url: abs('/'), text: [d.summary, d.details].filter(Boolean).join('\n\n') }] },
+ ...(d.sections || []).map((x) => ({ title: x.title, pages: (x.links || []).map((l) => ({ title: l.title, url: l.url, text: l.note || '' })) })),
+ ],
}));
}));
});
});
@@ -225,6 +225,15 @@ const form = (fields) => ({ body: new URLSearchParams(fields).toString(), header
@@ -225,6 +225,15 @@ const form = (fields) => ({ body: new URLSearchParams(fields).toString(), header
assert.equal((await t.get('/api/v1/glyphs/drafts?status=nope', { as: boss })).status, 422);
assert.equal((await t.get('/api/v1/glyphs/drafts?status=nope', { as: boss })).status, 422);
});
});
+ await check('llms-full.txt (SEO-33): the site in full, from the same descriptor as llms.txt', async () => {
+ const r = await t.get('/llms-full.txt');
+ assert.strictEqual(r.status, 200);
+ assert.match(r.headers.get('content-type') || '', /^text\/plain/);
+ assert.ok(r.text.startsWith('# OpenVibe.Design'), r.text.slice(0, 60));
+ assert.ok(r.text.length > 500, `${r.text.length} characters`);
+ assert.match(r.text, /## About\n\n### /);
+ });
+
await check('it is in the navbar, the sitemap and llms.txt', async () => {
await check('it is in the navbar, the sitemap and llms.txt', async () => {
assert.ok((await t.get('/sitemap.xml')).text.includes('/icons</loc>'), 'sitemap');
assert.ok((await t.get('/sitemap.xml')).text.includes('/icons</loc>'), 'sitemap');
assert.ok((await t.get('/llms.txt')).text.includes('/icons'), 'llms.txt');
assert.ok((await t.get('/llms.txt')).text.includes('/icons'), 'llms.txt');