Download scripts/check-entry-graphs.mjs from SaylorTwift/pi: direct link, hf CLI and curl.
- Browser
- Download file 5.42 kB
-
https://huggingface.co/SaylorTwift/pi/resolve/main/scripts/check-entry-graphs.mjs
- Command line
-
hf download hf://SaylorTwift/pi/scripts/check-entry-graphs.mjs
-
curl -L -o check-entry-graphs.mjs https://huggingface.co/SaylorTwift/pi/resolve/main/scripts/check-entry-graphs.mjs
5.42 kB
| /** | |
| * Entry points are cost contracts. | |
| * | |
| * A package's `exports` map is the only place that says which modules are public, and one stray | |
| * `export *` can silently make a narrow entry drag an entire barrel: importing a 1-file pure | |
| * function through a barrel costs ~37 MB of evaluated module graph, and nothing fails until someone | |
| * measures a process. This walks the value-import graph of every declared entry point and enforces a | |
| * budget per entry, so that regression fails at commit time instead. | |
| * | |
| * Only value imports count. `import type` / `export type` are erased before Node sees them. | |
| */ | |
| import { existsSync, readdirSync, readFileSync, statSync } from "node:fs"; | |
| import { dirname, relative, resolve } from "node:path"; | |
| import { fileURLToPath } from "node:url"; | |
| const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), ".."); | |
| /** Workspace package name -> its source root, so cross-package imports are followed. */ | |
| const WORKSPACE = { | |
| "@earendil-works/chord": "packages/chord/src", | |
| "@earendil-works/pi-ai": "packages/ai/src", | |
| "@earendil-works/pi-agent-core": "packages/agent/src", | |
| "@earendil-works/pi-telemetry": "packages/telemetry/src", | |
| "@earendil-works/pi-tui": "packages/tui/src", | |
| }; | |
| /** | |
| * Budgets are deliberate. `.` and `./node` are batteries-included entries and stay unbounded; every | |
| * narrow entry states the graph it is allowed to reach. | |
| */ | |
| const BUDGETS = { | |
| "packages/ai": { | |
| "./utils/*": { maxFiles: 3, forbid: ["providers/", "api/", "index.ts"] }, | |
| }, | |
| "packages/agent": { | |
| "./harness/runtime/reducer": { maxFiles: 1 }, | |
| "./harness/context": { maxFiles: 6, forbid: ["harness/runtime/", "harness/execution/", "packages/ai/"] }, | |
| "./harness/env/nodejs": { maxFiles: 5, forbid: ["packages/ai/", "harness/runtime/"] }, | |
| "./harness/session": { maxFiles: 25, forbid: ["harness/runtime/", "harness/execution/", "packages/ai/src/index.ts"] }, | |
| }, | |
| }; | |
| const SPEC = /(?:^|\n)\s*(?:import|export)\s+(?!type\s)([^;]*?\sfrom\s*)?["']([^"']+)["']/g; | |
| function resolveSpec(spec, fromFile) { | |
| if (spec.startsWith("node:")) return null; | |
| if (spec.startsWith(".")) { | |
| const base = resolve(dirname(fromFile), spec); | |
| for (const candidate of [base, `${base}.ts`, `${base}/index.ts`]) { | |
| if (existsSync(candidate) && statSync(candidate).isFile()) return candidate; | |
| } | |
| return null; | |
| } | |
| for (const [name, src] of Object.entries(WORKSPACE)) { | |
| if (spec === name) return resolve(ROOT, src, "index.ts"); | |
| if (!spec.startsWith(`${name}/`)) continue; | |
| const tail = spec.slice(name.length + 1); | |
| for (const candidate of [`${tail}.ts`, `${tail}/index.ts`, tail]) { | |
| const file = resolve(ROOT, src, candidate); | |
| if (existsSync(file) && statSync(file).isFile()) return file; | |
| } | |
| } | |
| return null; // external dependency: not part of the workspace graph | |
| } | |
| function walk(entryFile) { | |
| const seen = new Set(); | |
| const queue = [entryFile]; | |
| while (queue.length > 0) { | |
| const file = queue.pop(); | |
| if (seen.has(file) || file.endsWith(".json")) continue; | |
| seen.add(file); | |
| for (const match of readFileSync(file, "utf8").matchAll(SPEC)) { | |
| const target = resolveSpec(match[2], file); | |
| if (target) queue.push(target); | |
| } | |
| } | |
| return seen; | |
| } | |
| /** `./dist/harness/context.js` in the exports map is `src/harness/context.ts` on disk. */ | |
| function sourceFor(pkgDir, distPath) { | |
| const rel = distPath.replace(/^\.\/dist\//, "").replace(/\.js$/, ".ts"); | |
| const file = resolve(ROOT, pkgDir, "src", rel); | |
| return existsSync(file) ? file : undefined; | |
| } | |
| function expand(pkgDir, entry, target) { | |
| if (!entry.includes("*")) return [[entry, target]]; | |
| const dir = resolve(ROOT, pkgDir, "src", dirname(target.replace(/^\.\/dist\//, ""))); | |
| if (!existsSync(dir)) return []; | |
| return readdirSync(dir) | |
| .filter((name) => name.endsWith(".ts")) | |
| .map((name) => [entry.replace("*", name.replace(/\.ts$/, "")), target.replace("*", name.replace(/\.ts$/, ""))]); | |
| } | |
| let failures = 0; | |
| for (const [pkgDir, budgets] of Object.entries(BUDGETS)) { | |
| const manifest = JSON.parse(readFileSync(resolve(ROOT, pkgDir, "package.json"), "utf8")); | |
| for (const [entry, budget] of Object.entries(budgets)) { | |
| const declared = manifest.exports?.[entry]; | |
| if (!declared) { | |
| console.error(`${pkgDir} declares no export "${entry}" but a budget exists for it`); | |
| failures += 1; | |
| continue; | |
| } | |
| const target = typeof declared === "string" ? declared : declared.import; | |
| for (const [name, distPath] of expand(pkgDir, entry, target)) { | |
| const source = sourceFor(pkgDir, distPath); | |
| if (!source) { | |
| console.error(`${pkgDir} export "${name}" points at ${distPath}, which has no source file`); | |
| failures += 1; | |
| continue; | |
| } | |
| const graph = [...walk(source)].map((file) => relative(ROOT, file)); | |
| if (graph.length > budget.maxFiles) { | |
| console.error( | |
| `${pkgDir} export "${name}" reaches ${graph.length} files, budget ${budget.maxFiles}\n` + | |
| graph.map((file) => ` ${file}`).join("\n"), | |
| ); | |
| failures += 1; | |
| } | |
| for (const pattern of budget.forbid ?? []) { | |
| const hit = graph.filter((file) => file.includes(pattern)); | |
| if (hit.length > 0) { | |
| console.error(`${pkgDir} export "${name}" must not reach ${pattern}:\n${hit.map((f) => ` ${f}`).join("\n")}`); | |
| failures += 1; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| if (failures > 0) { | |
| console.error(`\n${failures} entry-point budget violation(s).`); | |
| process.exit(1); | |
| } | |
| console.log("Entry point graphs are within budget."); | |