import { readFileSync, existsSync } from 'node:fs'; import { resolve, dirname, relative, extname } from 'node:path'; // Inspect only the graph reached from index.html; old chunks left in dist do not count. export function verifyTokenBuild(directory) { const root = resolve(directory); const visited = new Set(); function visit(path) { path = resolve(path); const rel = relative(root, path); if (rel.startsWith('..') || !existsSync(path) || visited.has(path)) return; visited.add(path); const text = readFileSync(path, 'utf8'); for (const match of text.matchAll(/["'`]((?:\.{0,2}\/)?[\w./-]+\.js)["'`]/g)) { const ref = match[1]; visit(ref.startsWith('/') ? resolve(root, ref.slice(1)) : resolve(dirname(path), ref)); } } visit(resolve(root, 'index.html')); const stats = [...visited].filter((path) => /[\\/]call-stats-[^\\/]+\.js$/.test(path)); if (stats.length !== 1 || !readFileSync(stats[0], 'utf8').includes('ModelUsageStats-')) { throw new Error('The active call statistics page does not include Token usage. Refusing this build.'); } const usage = [...visited].filter((path) => /[\\/]ModelUsageStats-[^\\/]+\.js$/.test(path)); const hasApi = [...visited].some((path) => extname(path) === '.js' && readFileSync(path, 'utf8').includes('/stats/model-usage/log')); if (!usage.length || !hasApi) throw new Error('The active Token component or usage API is missing.'); return { page: relative(root, stats[0]), component: relative(root, usage[0]), assets: visited.size }; } console.log(JSON.stringify(verifyTokenBuild(process.argv[2] || 'dist')));