Files
t3mp3st/scripts/check-pagenary-docsite.mjs
Joseph Magly 0c35a833b9 docs: add usage and developer documentation
Add user and developer documentation plus Pagenary docsite publishing support.

Includes Getting Started, Developer Guide, API and MCP references, Pagenary tenant metadata, npm scripts for sync/build/check/serve, and validation coverage for the generated docsite.

Closes #102
2026-07-20 12:59:53 -04:00

82 lines
2.3 KiB
JavaScript

#!/usr/bin/env node
import { access, readFile } from 'node:fs/promises';
import { join } from 'node:path';
const ROOT = process.cwd();
const TENANT_ID = 't3mp3st-docs';
const DIST = join(ROOT, 'dist', TENANT_ID);
const TENANT = join(ROOT, 'docsite', TENANT_ID);
async function exists(path) {
try {
await access(path);
return true;
} catch {
return false;
}
}
async function readJson(path) {
return JSON.parse(await readFile(path, 'utf8'));
}
function fail(message) {
console.error(`✖ ${message}`);
process.exitCode = 1;
}
async function main() {
const required = [
'index.html',
'manifest.js',
'sitemap.xml',
'robots.txt',
'llms.txt',
'search-index/manifest.json',
'search-index/metadata.json',
'content-index.json',
'documents.jsonl',
];
for (const rel of required) {
if (!(await exists(join(DIST, rel)))) fail(`missing ${join('dist', TENANT_ID, rel)}`);
}
const manifest = await readJson(join(TENANT, 'manifest.json'));
const expectedPages = flattenSections(manifest.sections || []).filter((section) => section.file).length;
const metadata = await readJson(join(DIST, 'search-index', 'metadata.json'));
const indexedPages = Array.isArray(metadata.pages) ? metadata.pages.length : 0;
if (indexedPages !== expectedPages) {
fail(`search metadata indexed ${indexedPages} page(s), expected ${expectedPages}`);
}
const sitemap = await readFile(join(DIST, 'sitemap.xml'), 'utf8');
const sitemapUrls = [...sitemap.matchAll(/<url>/g)].length;
if (sitemapUrls < expectedPages) {
fail(`sitemap has ${sitemapUrls} URL(s), expected at least ${expectedPages}`);
}
const llms = await readFile(join(DIST, 'llms.txt'), 'utf8');
if (!llms.includes('T3MP3ST Documentation') || !llms.includes('Getting Started')) {
fail('llms.txt does not include expected site/page metadata');
}
if (process.exitCode) process.exit(process.exitCode);
console.log(`Pagenary docsite artifacts verified: ${expectedPages} pages indexed.`);
}
function flattenSections(sections) {
const out = [];
for (const section of sections || []) {
out.push(section);
out.push(...flattenSections(section.sections || section.subsections || []));
}
return out;
}
main().catch((error) => {
console.error(error instanceof Error ? error.message : String(error));
process.exit(1);
});