Files
quixos-protocol/src/capability-language/workspace-cli.ts
T
Timothy J. Aveni ad2a851b94 Consolidate Reader source ownership and pinned application instances
Add exact recursive source checkout, independent Git/jj developer workbenches and source-only backup/recovery commands, with Workspace instance binding outside source. Qualify two empty Reader Graphs, packaged source commands, Agent VM compilation, exact Gitea read grants and reconciled Reader settings/annotation stability. Publish checked Reader Package/root revisions to canonical review branches and retention tags, retain all 57 repositories independently in private versioned storage, verify downloaded-backup recovery and advance the example pin.

Add bounded Central pin acquisition and selection-specific read-only identities, qualified against all 57 canonical repositories without write authority. Replace regex fork dependency discovery with compiler-parsed lock imports and rewrite proposals; preserve source identities and unrelated files, passing instance binding through packed and ordinary host checks.

Hosted run-pin versus authoring preparation and maintained duplicate removal remain pending. Live source selections, Template defaults and default source branches are unchanged.
2026-10-10 18:38:57 -07:00

168 lines
7.0 KiB
JavaScript

#!/usr/bin/env node
import { readFile, writeFile } from "node:fs/promises";
import process from "node:process";
import { compileWorkspaceRepository } from "./assembly.js";
import { createGitCapabilityResolver } from "./git-resolver.js";
import { loadQueryGenerator } from "./query-generator.js";
import { loadCheckedResources } from "./checked-resources.js";
import { profile } from "./profile.js";
import { compileExecutionPlan, packageBuildContexts } from "../execution-world/index.js";
import { bindingSchema, specializeBindingSchema } from "../bindings/index.js";
import {
planEvolution,
runtimeContracts,
type EvolutionReview,
type WorkspaceRevision,
} from "../capability-model/index.js";
const usage = `usage: quixos-workspace-compile --root DIRECTORY --checkout-root DIRECTORY
[--snapshot-map PATH] [--graph-out PATH] [--workspace-id ID] [--workspace-revision-id ID]
[--source-root-commit GIT_REV] [--baseline PLAN_JSON] [--evolution-out PATH]
[--reviews REVIEW_JSON] [--schemas-out PATH] [--execution-plan-out PATH] [--build-contexts-out PATH]
[--query-generator BUILD_MODULE_PATH] [--checked-resources NIX_MAP]
Resolves a workspace's recursive resource-lock graph, clones every exact
resource revision, validates standalone interface/package manifests, and emits
the checked workspace plan as JSON.`;
const parseArgs = (args: string[]) => {
const values = new Map<string, string>();
for (let index = 0; index < args.length; index += 2) {
const key = args[index];
const value = args[index + 1];
if (!key?.startsWith("--") || !value) throw new Error(usage);
values.set(key, value);
}
const rootDirectory = values.get("--root");
const checkoutRoot = values.get("--checkout-root");
if (!rootDirectory || !checkoutRoot) throw new Error(usage);
return {
rootDirectory,
checkoutRoot,
graphOut: values.get("--graph-out"),
schemasOut: values.get("--schemas-out"),
executionPlanOut: values.get("--execution-plan-out"),
buildContextsOut: values.get("--build-contexts-out"),
snapshotMap: values.get("--snapshot-map"),
workspaceId: values.get("--workspace-id"),
workspaceRevisionId: values.get("--workspace-revision-id"),
sourceRootCommit: values.get("--source-root-commit"),
baseline: values.get("--baseline"),
evolutionOut: values.get("--evolution-out"),
reviews: values.get("--reviews"),
queryGenerator: values.get("--query-generator"),
checkedResources: values.get("--checked-resources"),
};
};
const main = async () => {
if (process.argv.includes("--help") || process.argv.includes("-h")) {
process.stdout.write(`${usage}\n`);
return;
}
const options = parseArgs(process.argv.slice(2));
const resolveResource = await createGitCapabilityResolver({
checkoutRoot: options.checkoutRoot,
snapshotMap: options.snapshotMap,
});
const assemblyStarted = performance.now();
const assembled = await compileWorkspaceRepository({
rootDirectory: options.rootDirectory,
workspaceId: options.workspaceId,
workspaceRevisionId: options.workspaceRevisionId,
sourceRootCommit: options.sourceRootCommit,
resolveResource,
generateQueries: await loadQueryGenerator(options.queryGenerator),
checkedResource: await loadCheckedResources(options.checkedResources),
});
profile("workspace-assembly", assemblyStarted, { resources: assembled.resources.length });
if (options.graphOut) {
await writeFile(
options.graphOut,
`${JSON.stringify(
{
formatVersion: 1,
workspaceId: assembled.workspace.workspaceId,
quixos: assembled.lock.quixos,
directResources: [...assembled.directResources.entries()].map(([bindingKey, node]) => {
const [kind, binding] = bindingKey.split("\0");
return { kind, binding, resourceKey: node.key, directory: node.directory };
}),
resources: assembled.resources.map((node) => ({
key: node.key,
kind: node.kind,
source: node.source,
directory: node.directory,
...(node.resource.kind === "build"
? {}
: {
resourceId:
node.resource.kind === "interface"
? node.resource.revision.interfaceId
: node.resource.revision.packageId,
revisionId: node.resource.revision.revisionId,
}),
dependencies: [...node.dependencies.entries()].map(([binding, dependency]) => ({
binding,
resourceKey: dependency.key,
})),
})),
},
null,
2,
)}\n`,
);
}
const candidate = { ...assembled.workspace, executionContracts: runtimeContracts(assembled.workspace) };
if (options.executionPlanOut || options.buildContextsOut) {
const executionStarted = performance.now();
const plan = compileExecutionPlan(assembled.workspace);
// Machine-consumed immutable metadata should not spend its bounded input
// reservation on indentation. Its parsed allocation is charged separately.
if (options.executionPlanOut) await writeFile(options.executionPlanOut, `${JSON.stringify(plan)}\n`);
if (options.buildContextsOut)
await writeFile(options.buildContextsOut, JSON.stringify(packageBuildContexts(plan.definition.bindingSchema)));
profile("execution-plan-and-contexts", executionStarted);
}
if (options.schemasOut) {
const schemasStarted = performance.now();
const schemas: Record<string, unknown> = {};
for (const node of assembled.capabilityResources.filter((entry) => entry.kind === "package")) {
const closure = new Map<string, typeof node>();
const visit = (entry: typeof node) => {
if (closure.has(entry.key) || entry.kind === "build") return;
closure.set(entry.key, entry);
entry.dependencies.forEach(visit);
};
visit(node);
if (node.resource.kind !== "package") continue;
schemas[node.resource.revision.revisionId] = specializeBindingSchema(
bindingSchema({ resources: [...closure.values()] }),
candidate,
node.resource.revision.revisionId,
);
}
await writeFile(options.schemasOut, JSON.stringify(schemas));
profile("package-schemas", schemasStarted);
}
if (options.evolutionOut) {
const baseline = options.baseline
? (JSON.parse(await readFile(options.baseline, "utf8")) as WorkspaceRevision)
: null;
const reviews = options.reviews ? (JSON.parse(await readFile(options.reviews, "utf8")) as EvolutionReview[]) : [];
if (!Array.isArray(reviews)) throw new Error("Review file must contain an array");
await writeFile(
options.evolutionOut,
`${JSON.stringify(planEvolution(baseline, candidate, { reviews }), null, 2)}\n`,
);
}
process.stdout.write(`${JSON.stringify(candidate, null, 2)}\n`);
};
main().catch((error: unknown) => {
process.stderr.write(`${error instanceof Error ? (error.stack ?? error.message) : String(error)}\n`);
process.exitCode = 1;
});