openvibers/openvibe.zone Commits
/llms-full.txt holds the guide in full (SEO-33) (#140)
Changes
@@@ -171,6 +171,8 @@ async function createApp(opts = {}) {// ── Pages ───────────────────────────────────────────────app.use(rateLimit({ windowMs: 60_000, limit: Number(process.env.ZONE_RATE_LIMIT_PER_MIN) || 300, standardHeaders: true, legacyHeaders: false }));const pageRoutes = createPageRoutes(ctx);++ // The guide in full for /llms-full.txt (http/discovery.js reads it at request time; SEO-33).++ ctx.publicViews = pageRoutes.publicViews;// The agent layer (openvibe-shared/agent-layer): /.well-known/agent.json and the Markdown twins of the public// pages. The pages keep their own routes — a signed-in person's projects and forms are theirs — so only the// manifest and twin requests reach this mount; the pages advertise the twin themselves.@@@ -83,10 +83,16 @@ function createDiscoveryRoutes(ctx) {}));});-- r.get('/llms-full.txt', (_req, res) => {-- const pages = publicPages().map((e) => ({ url: e.path, title: PAGE_TEXT[e.path][0], text: PAGE_TEXT[e.path][1] }));++ r.get('/llms-full.txt', async (_req, res) => {++ // The guide (/docs) in full, from the page's own builder; the other pages one line each (SEO-33: it was 493++ // characters in all).++ let docs = null;++ try { docs = ctx.publicViews ? await ctx.publicViews.docs() : null; } catch { /* the one-line description stands */ }++ const pages = publicPages().map((e) => (e.path === '/docs' && docs && docs.body++ ? { url: e.path, title: PAGE_TEXT[e.path][0], html: String(docs.body) }++ : { url: e.path, title: PAGE_TEXT[e.path][0], text: PAGE_TEXT[e.path][1] }));res.type('text/plain').set('Cache-Control', TEXT).send(seo.llmsFull({-- site: SITE_NAME, summary: 'Every public page of OpenVibe.Zone, one line each.', base: site, maxBytes: 64 * 1024,++ site: SITE_NAME, summary: 'Every public page of OpenVibe.Zone, the guide in full.', base: site, maxBytes: 64 * 1024,sections: [{ title: 'Pages', pages }],}));});@@@ -32,6 +32,10 @@ const { boot, check, done } = require('./helpers/boot');await check('llms-full.txt lists every public page', async () => {const r = await t.get('/llms-full.txt');for (const s of ['OpenVibe.Zone home', 'Using OpenVibe.Zone', 'What shipped on OpenVibe.Zone']) assert.ok(r.text.includes(s), s);++ // SEO-33: the guide in full, as text (it was one line a page, 493 characters).++ assert.match(r.text, /The S3 endpoint/);++ assert.ok(r.text.length > 2000, `${r.text.length} characters`);++ assert.ok(!/<\/?(h1|h2|p|ul|li|code|section)\b[^>]*>/i.test(r.text), 'text, no markup');});} finally { await t.close(); }done();
@@ -171,6 +171,8 @@ async function createApp(opts = {}) {
@@ -171,6 +171,8 @@ async function createApp(opts = {}) {
// ── Pages ───────────────────────────────────────────────
// ── Pages ───────────────────────────────────────────────
app.use(rateLimit({ windowMs: 60_000, limit: Number(process.env.ZONE_RATE_LIMIT_PER_MIN) || 300, standardHeaders: true, legacyHeaders: false }));
app.use(rateLimit({ windowMs: 60_000, limit: Number(process.env.ZONE_RATE_LIMIT_PER_MIN) || 300, standardHeaders: true, legacyHeaders: false }));
const pageRoutes = createPageRoutes(ctx);
const pageRoutes = createPageRoutes(ctx);
+ // The guide in full for /llms-full.txt (http/discovery.js reads it at request time; SEO-33).
+ ctx.publicViews = pageRoutes.publicViews;
// The agent layer (openvibe-shared/agent-layer): /.well-known/agent.json and the Markdown twins of the public
// The agent layer (openvibe-shared/agent-layer): /.well-known/agent.json and the Markdown twins of the public
// pages. The pages keep their own routes — a signed-in person's projects and forms are theirs — so only the
// pages. The pages keep their own routes — a signed-in person's projects and forms are theirs — so only the
// manifest and twin requests reach this mount; the pages advertise the twin themselves.
// manifest and twin requests reach this mount; the pages advertise the twin themselves.
@@ -83,10 +83,16 @@ function createDiscoveryRoutes(ctx) {
@@ -83,10 +83,16 @@ function createDiscoveryRoutes(ctx) {
}));
}));
});
});
- r.get('/llms-full.txt', (_req, res) => {
- const pages = publicPages().map((e) => ({ url: e.path, title: PAGE_TEXT[e.path][0], text: PAGE_TEXT[e.path][1] }));
+ r.get('/llms-full.txt', async (_req, res) => {
+ // The guide (/docs) in full, from the page's own builder; the other pages one line each (SEO-33: it was 493
+ // characters in all).
+ let docs = null;
+ try { docs = ctx.publicViews ? await ctx.publicViews.docs() : null; } catch { /* the one-line description stands */ }
+ const pages = publicPages().map((e) => (e.path === '/docs' && docs && docs.body
+ ? { url: e.path, title: PAGE_TEXT[e.path][0], html: String(docs.body) }
+ : { url: e.path, title: PAGE_TEXT[e.path][0], text: PAGE_TEXT[e.path][1] }));
res.type('text/plain').set('Cache-Control', TEXT).send(seo.llmsFull({
res.type('text/plain').set('Cache-Control', TEXT).send(seo.llmsFull({
- site: SITE_NAME, summary: 'Every public page of OpenVibe.Zone, one line each.', base: site, maxBytes: 64 * 1024,
+ site: SITE_NAME, summary: 'Every public page of OpenVibe.Zone, the guide in full.', base: site, maxBytes: 64 * 1024,
sections: [{ title: 'Pages', pages }],
sections: [{ title: 'Pages', pages }],
}));
}));
});
});
@@ -32,6 +32,10 @@ const { boot, check, done } = require('./helpers/boot');
@@ -32,6 +32,10 @@ const { boot, check, done } = require('./helpers/boot');
await check('llms-full.txt lists every public page', async () => {
await check('llms-full.txt lists every public page', async () => {
const r = await t.get('/llms-full.txt');
const r = await t.get('/llms-full.txt');
for (const s of ['OpenVibe.Zone home', 'Using OpenVibe.Zone', 'What shipped on OpenVibe.Zone']) assert.ok(r.text.includes(s), s);
for (const s of ['OpenVibe.Zone home', 'Using OpenVibe.Zone', 'What shipped on OpenVibe.Zone']) assert.ok(r.text.includes(s), s);
+ // SEO-33: the guide in full, as text (it was one line a page, 493 characters).
+ assert.match(r.text, /The S3 endpoint/);
+ assert.ok(r.text.length > 2000, `${r.text.length} characters`);
+ assert.ok(!/<\/?(h1|h2|p|ul|li|code|section)\b[^>]*>/i.test(r.text), 'text, no markup');
});
});
} finally { await t.close(); }
} finally { await t.close(); }
done();
done();