0c46850973
- run a singleton Codex App Server adapter in each dev workspace - gate Web Studio with a reloadable fragment-token to HttpOnly-session exchange - add ChatGPT device login and streamed chat to Web Studio - isolate authoring access in a declarative NixOS service account - split Web Studio canvas, object, panel, and model concerns - check generated Quixos protocol clients for drift - resolve same-repository quixos.lock fragments deterministically - preserve the collaborative canvas gesture fixes
87 lines
3.2 KiB
JavaScript
87 lines
3.2 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
import { writeFile } from "node:fs/promises";
|
|
import process from "node:process";
|
|
import { compileWorkspaceRepository } from "./assembly.js";
|
|
import { createGitCapabilityResolver } from "./git-resolver.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]
|
|
|
|
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"),
|
|
snapshotMap: values.get("--snapshot-map"),
|
|
workspaceId: values.get("--workspace-id"),
|
|
workspaceRevisionId: values.get("--workspace-revision-id"),
|
|
sourceRootCommit: values.get("--source-root-commit"),
|
|
};
|
|
};
|
|
|
|
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 assembled = await compileWorkspaceRepository({
|
|
rootDirectory: options.rootDirectory,
|
|
workspaceId: options.workspaceId,
|
|
workspaceRevisionId: options.workspaceRevisionId,
|
|
sourceRootCommit: options.sourceRootCommit,
|
|
resolveResource,
|
|
});
|
|
|
|
if (options.graphOut) {
|
|
await writeFile(options.graphOut, `${JSON.stringify({
|
|
formatVersion: 1,
|
|
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,
|
|
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`);
|
|
}
|
|
process.stdout.write(`${JSON.stringify(assembled.workspace, null, 2)}\n`);
|
|
};
|
|
|
|
main().catch((error: unknown) => {
|
|
process.stderr.write(`${error instanceof Error ? error.stack ?? error.message : String(error)}\n`);
|
|
process.exitCode = 1;
|
|
});
|