Format authored monorepo code with pinned language formatters

This commit is contained in:
Timothy J. Aveni
2026-09-15 15:23:24 -07:00
parent a174faea5c
commit 00fc2b9ff1
69 changed files with 5135 additions and 3306 deletions
+61 -24
View File
@@ -5,48 +5,74 @@ import path from "node:path";
import { parseQx, walkSyntax } from "./source.js";
import { authoringContext } from "./authoring-context.js";
import { readQxSource } from "./source-loader.js";
import {loadQuixosLock} from "../resource-lock/index.js";
import { loadQuixosLock } from "../resource-lock/index.js";
const execFile = promisify(callback);
const git = async (root: string, args: string[]) => (await execFile("git", ["-C", root, ...args], {
maxBuffer: 8 * 1024 * 1024, env: { ...process.env, GIT_TERMINAL_PROMPT: "0" },
})).stdout;
const git = async (root: string, args: string[]) =>
(
await execFile("git", ["-C", root, ...args], {
maxBuffer: 8 * 1024 * 1024,
env: { ...process.env, GIT_TERMINAL_PROMPT: "0" },
})
).stdout;
const message = (error: unknown) => String(error instanceof Error ? error.message : error).slice(0, 2000);
/** Syntax-only contract inspection is deliberately NOT verification evidence.
* Each file can recover independently; current valid files always win. */
export async function inspectAuthoringRepository(root: string, historyLimit = 100) {
const names = (await git(root, ["ls-files", "-z", "--cached", "--others", "--exclude-standard"]))
.split("\0").filter(name => name.endsWith(".qx"));
if (names.length > 128) throw new Error("Repository inspection exceeds 128 QX files; split the resource into smaller repositories");
.split("\0")
.filter((name) => name.endsWith(".qx"));
if (names.length > 128)
throw new Error("Repository inspection exceeds 128 QX files; split the resource into smaller repositories");
const files = [];
for (const name of [...new Set(names)].sort()) {
let source = "", errors: unknown[] = [], revision: string | null = null;
let source = "",
errors: unknown[] = [],
revision: string | null = null;
try {
source = await readQxSource(root, name);
if (source.length > 262144) throw new Error(`Inspection file exceeds 256 KiB: ${name}`);
errors = parseQx(source, name).diagnostics;
} catch (error) { errors = [{ message: message(error) }]; }
} catch (error) {
errors = [{ message: message(error) }];
}
const currentErrors = errors;
if (errors.length) {
// Git can traverse jj's immutable commit DAG without mutating/snapshotting @.
const head = await execFile("jj", ["--ignore-working-copy", "log", "--no-graph", "-r", "@", "-T", "commit_id"],
{ cwd: root, env: { ...process.env, QUIXOS_JJ_NO_CHECKPOINT: "1" } }).then(r => r.stdout.trim(), () => "HEAD");
const head = await execFile("jj", ["--ignore-working-copy", "log", "--no-graph", "-r", "@", "-T", "commit_id"], {
cwd: root,
env: { ...process.env, QUIXOS_JJ_NO_CHECKPOINT: "1" },
}).then(
(r) => r.stdout.trim(),
() => "HEAD",
);
const commits = await git(root, ["rev-list", `--max-count=${historyLimit}`, head, "--", name]).catch(() => "");
for (const commit of commits.trim().split("\n").filter(Boolean)) {
const historical = await git(root, ["show", `${commit}:${name}`]).catch(() => null);
if (historical === null || historical.length > 262144) continue;
if (!parseQx(historical, name).diagnostics.length) {
source = historical; revision = commit; errors = []; break;
source = historical;
revision = commit;
errors = [];
break;
}
}
}
const syntax = errors.length ? null : parseQx(source, name);
files.push({ file: name, status: errors.length ? "unavailable" : revision ? "historical" : "current",
revision, currentErrors: currentErrors.slice(0, 20), omittedErrors: Math.max(0, currentErrors.length - 20),
declarations: syntax ? [...walkSyntax(syntax.root)]
.filter(node => /^(?:interface|package|atom|state|edge|method|function|event|conformance)\w*Decl$/.test(node.kind))
.map(node => ({ kind: node.kind, source: source.slice(node.start, node.end) })) : [],
files.push({
file: name,
status: errors.length ? "unavailable" : revision ? "historical" : "current",
revision,
currentErrors: currentErrors.slice(0, 20),
omittedErrors: Math.max(0, currentErrors.length - 20),
declarations: syntax
? [...walkSyntax(syntax.root)]
.filter((node) =>
/^(?:interface|package|atom|state|edge|method|function|event|conformance)\w*Decl$/.test(node.kind),
)
.map((node) => ({ kind: node.kind, source: source.slice(node.start, node.end) }))
: [],
});
}
return { verificationEvidence: false as const, resolutionChecked: false as const, files };
@@ -56,21 +82,32 @@ export async function inspectWorkbench(start: string, selector?: string) {
const context = await authoringContext(start);
if (!selector || selector === ".") {
const relative = path.relative(context.workbench, await realpath(start));
selector = context.resources.find(entry => relative === entry.directory || relative.startsWith(entry.directory + path.sep))?.directory ?? "root";
selector =
context.resources.find((entry) => relative === entry.directory || relative.startsWith(entry.directory + path.sep))
?.directory ?? "root";
}
const lock = await loadQuixosLock(path.join(context.workbench, "root/quixos.lock"));
const aliases = lock.ok ? lock.lock.resources.filter(entry => entry.binding === selector) : [];
const selected = context.resources.filter(entry => !selector || selector === entry.directory ||
selector === entry.resourceId || selector === path.basename(entry.directory) || aliases.some(alias => alias.kind === entry.kind && alias.source.repository === entry.source?.repository));
const aliases = lock.ok ? lock.lock.resources.filter((entry) => entry.binding === selector) : [];
const selected = context.resources.filter(
(entry) =>
!selector ||
selector === entry.directory ||
selector === entry.resourceId ||
selector === path.basename(entry.directory) ||
aliases.some((alias) => alias.kind === entry.kind && alias.source.repository === entry.source?.repository),
);
if (!selected.length) throw new Error(`No registered resource matches ${selector}`);
if (selector && selected.length > 1) throw new Error(`Ambiguous resource ${selector}; use its resource ID or directory`);
if (selector && selected.length > 1)
throw new Error(`Ambiguous resource ${selector}; use its resource ID or directory`);
const resources = [];
for (const entry of selected) {
try {
const root = path.join(context.workbench, entry.directory);
if (await realpath(root) !== root) throw new Error("Managed checkout crosses a symlink");
resources.push({ ...entry, ...await inspectAuthoringRepository(root) });
} catch (error) { resources.push({ ...entry, error: message(error) }); }
if ((await realpath(root)) !== root) throw new Error("Managed checkout crosses a symlink");
resources.push({ ...entry, ...(await inspectAuthoringRepository(root)) });
} catch (error) {
resources.push({ ...entry, error: message(error) });
}
}
return { workbench: context.workbench, verificationEvidence: false, resources };
}