Files
openclaw/scripts/check-tsgo-core-boundary.mjs
Peter SteinbergerandGitHub 29ef6f8637 fix(scripts): resolve remaining repo tools through the worktree-aware helper (#111417)
Follow-up to #111393: run-tsgo, check-tsgo-core-boundary, profile-tsgo,
and the format-docs oxfmt shim still resolved node_modules/.bin from the
current checkout only, so dependency-less linked worktrees died with
ENOENT before oxlint's boundary prep could run. All four now use
resolveRepoToolBinPath, completing local lint/typecheck tooling for
linked worktrees.
2026-07-19 06:47:32 -07:00

69 lines
2.4 KiB
JavaScript

#!/usr/bin/env node
// Enforces core tsgo project boundaries and sparse-checkout safety.
import { spawnSync } from "node:child_process";
import path from "node:path";
import { resolveRepoToolBinPath } from "./lib/local-heavy-check-runtime.mjs";
import { createManagedCommandInvocation } from "./lib/managed-child-process.mjs";
const repoRoot = path.resolve(import.meta.dirname, "..");
const tsgoPath = resolveRepoToolBinPath("tsgo", { cwd: repoRoot });
const coreGraphs = [
{ name: "core", config: "tsconfig.core.json" },
{ name: "ui", config: "tsconfig.ui.json" },
{ name: "core-test", config: "test/tsconfig/tsconfig.core.test.json" },
{ name: "core-test-agents", config: "test/tsconfig/tsconfig.core.test.agents.json" },
{ name: "core-test-non-agents", config: "test/tsconfig/tsconfig.core.test.non-agents.json" },
];
function normalizeFilePath(filePath) {
const normalized = filePath.trim().replaceAll("\\", "/");
const normalizedRoot = repoRoot.replaceAll("\\", "/");
if (normalized.startsWith(`${normalizedRoot}/`)) {
return normalized.slice(normalizedRoot.length + 1);
}
return normalized;
}
function listGraphFiles(graph) {
const tsgo = createManagedCommandInvocation({
args: ["-p", graph.config, "--pretty", "false", "--listFilesOnly"],
bin: tsgoPath,
});
const result = spawnSync(tsgo.command, tsgo.args, {
cwd: repoRoot,
encoding: "utf8",
maxBuffer: 256 * 1024 * 1024,
shell: tsgo.shell,
windowsVerbatimArguments: tsgo.windowsVerbatimArguments,
});
if (result.error) {
throw result.error;
}
if ((result.status ?? 1) !== 0) {
const output = [result.stdout, result.stderr].filter(Boolean).join("\n");
throw new Error(`${graph.name} file listing failed with exit code ${result.status}\n${output}`);
}
return (result.stdout ?? "").split(/\r?\n/u).map(normalizeFilePath).filter(Boolean);
}
const violations = [];
for (const graph of coreGraphs) {
const extensionFiles = listGraphFiles(graph).filter((file) => file.startsWith("extensions/"));
for (const file of extensionFiles) {
violations.push(`${graph.name}: ${file}`);
}
}
if (violations.length > 0) {
console.error("Core tsgo graphs must not include bundled extension files:");
for (const violation of violations) {
console.error(`- ${violation}`);
}
console.error(
"Move extension-owned behavior behind plugin SDK contracts, public artifacts, or extension-local tests.",
);
process.exit(1);
}