Source files
${source}Assets
- ${assetLinks}
import { createHash } from "node:crypto"; import { lstat, mkdir, readFile, readdir, writeFile } from "node:fs/promises"; import { dirname, extname, resolve } from "node:path"; // Only these authored inputs are public. Build output, private deployment state, // hidden files, dependencies, and symlinks are never traversed. const textRoots = ["src", "scripts", "tests"]; const textExtensions = new Set([ ".html", ".css", ".js", ".mjs", ".json", ".md", ]); const assetExtensions = new Set([ ".svg", ".png", ".jpg", ".jpeg", ".webp", ".avif", ".woff", ".woff2", ".mp4", ".webm", ]); const documents = [ ".vercelignore", "package.json", "package-lock.json", "vercel.json", "README.md", "ASSETS.md", "MOTION.md", "CAPTURES.md", "CONCEPT-MAP.md", "DEPLOYMENT.md", ]; const excludedDirectories = new Set([ "node_modules", "dist", "reports", "captures", ]); function escapeHtml(value) { return value.replace( /[&<>"']/g, (character) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'", })[character], ); } async function listFiles(root, directory, extensions) { let entries; try { if (!(await lstat(resolve(root, directory))).isDirectory()) return []; entries = await readdir(resolve(root, directory), { withFileTypes: true }); } catch (error) { if (error.code === "ENOENT") return []; throw error; } const paths = await Promise.all( entries.map(async (entry) => { if (entry.name.startsWith(".") || entry.isSymbolicLink()) return []; const path = `${directory}/${entry.name}`; if (entry.isDirectory()) { return excludedDirectories.has(entry.name) ? [] : listFiles(root, path, extensions); } return entry.isFile() && extensions.has(extname(entry.name)) ? [path] : []; }), ); return paths.flat(); } async function existingDocuments(root) { const paths = await Promise.all( documents.map(async (path) => { try { return (await lstat(resolve(root, path))).isFile() ? [path] : []; } catch (error) { if (error.code === "ENOENT") return []; throw error; } }), ); return paths.flat(); } function metadata(path, url, content) { return { path, url, bytes: content.length, sha256: createHash("sha256").update(content).digest("hex"), }; } function indexPage(files, assets) { const source = files .map( ({ path, url, content }) => ` `, ) .join("\n"); const assetLinks = assets .map( ({ path, url }) => `
Complete authored HTML, CSS, JavaScript, build tools, tests, and local asset references. Expand a file to read it, or fetch the complete text bundle to recreate the project.