feat: release design system engine, studio and component contracts

This commit is contained in:
Clintchiz committed 2026-10-19 13:09:03 +05:30
1 parent ff1065fb27
commit 3943b946d6
693 files changed
+175546 -3894

No files matched your search

+227
View File
@@ -0,0 +1,227 @@
/** Local release preparation only. Never authenticates to or publishes to a registry. */
import {
existsSync,
readdirSync,
readFileSync,
writeFileSync,
mkdirSync,
mkdtempSync,
rmSync,
} from "node:fs";
import { basename, dirname, join, resolve, sep } from "node:path";
import { tmpdir } from "node:os";
import { spawnSync } from "node:child_process";
import { validateAndHashStage } from "./lib/package-integrity.ts";
const root = resolve(import.meta.dir, "..");
const output = join(root, "output", "design-system-phase-7");
const stage = join(root, ".publish-design");
const mode = process.argv[2] ?? "plan";
const all = new Map(
readdirSync(join(root, "packages")).flatMap((name) => {
const file = join(root, "packages", name, "package.json");
if (!existsSync(file)) return [];
const manifest = JSON.parse(readFileSync(file, "utf8"));
return [[manifest.name, { directory: name, ...manifest }]];
}),
);
const names = new Set<string>();
function visit(name: string) {
if (names.has(name)) return;
const pkg = all.get(name);
if (!pkg) throw Error("Missing workspace package " + name);
names.add(name);
for (const dependency of Object.keys({
...pkg.dependencies,
...pkg.optionalDependencies,
...pkg.peerDependencies,
}))
if (dependency.startsWith("@wrnexus/")) visit(dependency);
}
for (const name of ["@wrnexus/design-system", "@wrnexus/design-studio", "@wrnexus/mcp"])
visit(name);
mkdirSync(output, { recursive: true });
const plan = {
formatVersion: 1,
stageDirectory: stage,
packages: [...names].map((name) => ({ name, version: all.get(name).version })),
schemaVersion: 1,
contractVersion: 1,
designPackageVersion: 1,
registryAvailability: "not-checked",
published: false,
notes: [
"Source versions remain unchanged. Confirm unused release versions before publication.",
"Use the existing version/release process for production; this command only stages and packs locally.",
"Production-wide API/visual/type gates must pass separately before publication.",
],
};
writeFileSync(join(output, "release-plan.json"), JSON.stringify(plan, null, 2));
function run(command: string, args: string[], cwd = root) {
const result = spawnSync(command, args, {
cwd,
encoding: "utf8",
maxBuffer: 20 * 1024 * 1024,
env: { ...process.env, WRNEXUS_DESIGN_REPORT: join(output, "consumer-report.json") },
});
if (result.status !== 0)
throw Error(
`${basename(command)} failed: ${result.error?.message ?? result.stderr ?? result.stdout}`,
);
return result.stdout;
}
if (mode === "plan") {
console.log(JSON.stringify(plan, null, 2));
} else if (mode === "stage") {
console.log(
run(process.execPath, [
"run",
"scripts/publish-packages.ts",
"design-system",
"design-studio",
"mcp",
"--with-dependencies",
"--stage-root=.publish-design",
]),
);
} else if (mode === "check") {
writeFileSync(
join(output, "consumer-report.json"),
JSON.stringify({ packagingVerified: false, published: false, status: "running" }, null, 2),
);
const integrity = JSON.parse(readFileSync(join(stage, "PACKAGE-INTEGRITY.json"), "utf8"));
if (
integrity.packages.length !== names.size ||
integrity.packages.some(
(pkg: { name: string; version: string }) =>
!names.has(pkg.name) || pkg.version !== all.get(pkg.name)?.version,
)
)
throw Error("Staged closure differs from release plan. Restage all design packages.");
const node = Bun.which("node");
if (!node) throw Error("Node.js with npm is required to verify tarballs.");
const npm = join(dirname(node), "node_modules", "npm", "bin", "npm-cli.js");
if (!existsSync(npm)) throw Error("Unable to locate npm CLI.");
const tarballs = join(output, "tarballs");
mkdirSync(tarballs, { recursive: true });
const dependencies: Record<string, string> = {};
const packed = [];
for (const pkg of integrity.packages) {
const folder = join(stage, pkg.name.slice("@wrnexus/".length));
const manifest = JSON.parse(readFileSync(join(folder, "package.json"), "utf8"));
const actual = validateAndHashStage(folder, manifest);
if (JSON.stringify(actual) !== JSON.stringify(pkg))
throw Error("Staged integrity mismatch for " + pkg.name);
const files = JSON.parse(
run(node, [
npm,
"pack",
folder,
"--pack-destination",
tarballs,
"--json",
"--ignore-scripts",
]),
);
dependencies[pkg.name] = "file:" + join(tarballs, files[0].filename).replace(/\\/g, "/");
packed.push({
name: pkg.name,
version: manifest.version,
filename: files[0].filename,
integrity: files[0].integrity,
});
}
writeFileSync(join(output, "tarballs.json"), JSON.stringify(packed, null, 2));
const consumer = mkdtempSync(join(tmpdir(), "wrnexus-design-release-"));
try {
writeFileSync(
join(consumer, "package.json"),
JSON.stringify({
name: "design-release-consumer",
private: true,
type: "module",
dependencies,
}),
);
console.log(
run(node, [npm, "install", "--ignore-scripts", "--no-audit", "--no-fund"], consumer),
);
writeFileSync(
join(consumer, "probe.ts"),
readFileSync(join(root, "scripts", "design-release-consumer.ts"), "utf8"),
);
console.log(run(process.execPath, ["probe.ts"], consumer));
writeFileSync(
join(consumer, "types.ts"),
'import {CORE_DESIGN_SYSTEMS} from "@wrnexus/design-system"; import {createDesignPackage} from "@wrnexus/design-system/package"; import {StudioSession} from "@wrnexus/design-studio"; import {planDesignUpgrade} from "@wrnexus/design-studio/upgrades"; import {createFrameworkMcpServer} from "@wrnexus/mcp"; const session = new StudioSession(CORE_DESIGN_SYSTEMS.square); const artifact = await createDesignPackage(session.valid); await planDesignUpgrade(session, JSON.stringify(artifact)); createFrameworkMcpServer(".", {design:true,designWrite:true}); const recovery: string | undefined = session.recoverySource; console.log(recovery);',
);
writeFileSync(
join(consumer, "tsconfig.json"),
JSON.stringify({
compilerOptions: {
noEmit: true,
module: "ESNext",
moduleResolution: "bundler",
target: "ESNext",
skipLibCheck: true,
types: [],
lib: ["ESNext", "DOM"],
},
files: ["types.ts"],
}),
);
run(
node,
[join(root, "node_modules", "typescript", "bin", "tsc"), "--project", "tsconfig.json"],
consumer,
);
console.log("Installed package declarations passed consumer type checking.");
} finally {
// The path comes exclusively from mkdtemp; verify its workspace-independent boundary before removal.
if (
!resolve(consumer).startsWith(resolve(tmpdir()) + sep) ||
!basename(consumer).startsWith("wrnexus-design-release-")
)
console.error("Skipped cleanup: invalid consumer boundary.");
else if (process.argv.includes("--keep-consumer")) {
writeFileSync(
join(output, "consumer-path.json"),
JSON.stringify({ directory: consumer }, null, 2),
);
console.log("Retained installed consumer for local QA: " + consumer);
} else rmSync(consumer, { recursive: true, force: true });
}
const solo = mkdtempSync(join(tmpdir(), "wrnexus-design-release-"));
try {
writeFileSync(
join(solo, "package.json"),
JSON.stringify({
name: "mcp-only-release-consumer",
private: true,
type: "module",
dependencies: { "@wrnexus/mcp": dependencies["@wrnexus/mcp"] },
}),
);
run(node, [npm, "install", "--ignore-scripts", "--no-audit", "--no-fund"], solo);
writeFileSync(
join(solo, "probe.ts"),
'import assert from "node:assert/strict"; import {createFrameworkMcpServer} from "@wrnexus/mcp"; import {existsSync} from "node:fs"; assert.equal(existsSync("node_modules/@wrnexus/design-studio"),false); assert.equal(createFrameworkMcpServer(".").tools().length,8); await assert.rejects(createFrameworkMcpServer(".",{design:true}).call("wrnexus_design_context"),/WRN-MCP-DESIGN-INSTALL/); console.log("MCP-only install keeps default APIs without requiring Studio.");',
);
console.log(run(process.execPath, ["probe.ts"], solo));
} finally {
if (
resolve(solo).startsWith(resolve(tmpdir()) + sep) &&
basename(solo).startsWith("wrnexus-design-release-")
)
rmSync(solo, { recursive: true, force: true });
}
const reportPath = join(output, "consumer-report.json");
const report = JSON.parse(readFileSync(reportPath, "utf8"));
report.packagingVerified = true;
report.checkedAt = new Date().toISOString();
report.checks.push(
"installed declaration consumer type check",
"MCP-only installation without optional Studio peer",
);
writeFileSync(reportPath, JSON.stringify(report, null, 2));
console.log("Local tarballs verified. No registry publication performed.");
} else throw Error("Usage: bun scripts/prepare-design-release.ts plan | stage | check");