mirror of
https://github.com/openai/codex.git
synced 2026-11-14 21:40:39 +00:00
feat: add codex web terminal
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env node
|
||||
import { createHash } from "node:crypto";
|
||||
import {
|
||||
cpSync,
|
||||
existsSync,
|
||||
mkdirSync,
|
||||
readdirSync,
|
||||
readFileSync,
|
||||
rmSync,
|
||||
} from "node:fs";
|
||||
import { dirname, join, relative, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const packageRoot = resolve(dirname(__filename), "..");
|
||||
const repoRoot = resolve(packageRoot, "..");
|
||||
const distRoot = join(packageRoot, "dist");
|
||||
const rustAssetsRoot = join(repoRoot, "codex-rs", "web-server", "assets");
|
||||
const check = process.argv.includes("--check");
|
||||
|
||||
if (!existsSync(join(distRoot, "index.html"))) {
|
||||
throw new Error("Missing dist/index.html. Run the codex-webui build first.");
|
||||
}
|
||||
|
||||
if (check) {
|
||||
const diff = diffTrees(distRoot, rustAssetsRoot);
|
||||
if (diff.length > 0) {
|
||||
throw new Error(
|
||||
`codex web assets are out of date:\n${diff.map((item) => ` ${item}`).join("\n")}`,
|
||||
);
|
||||
}
|
||||
console.log("codex web Rust assets are up to date.");
|
||||
} else {
|
||||
rmSync(rustAssetsRoot, { force: true, recursive: true });
|
||||
mkdirSync(rustAssetsRoot, { recursive: true });
|
||||
cpSync(distRoot, rustAssetsRoot, { recursive: true });
|
||||
console.log(
|
||||
`Synced ${relative(repoRoot, distRoot)} to ${relative(repoRoot, rustAssetsRoot)}.`,
|
||||
);
|
||||
}
|
||||
|
||||
function diffTrees(leftRoot, rightRoot) {
|
||||
const leftFiles = listFiles(leftRoot);
|
||||
const rightFiles = listFiles(rightRoot);
|
||||
const allFiles = new Set([...leftFiles.keys(), ...rightFiles.keys()]);
|
||||
const diff = [];
|
||||
|
||||
for (const file of [...allFiles].sort()) {
|
||||
const left = leftFiles.get(file);
|
||||
const right = rightFiles.get(file);
|
||||
if (!left) {
|
||||
diff.push(`unexpected ${file}`);
|
||||
} else if (!right) {
|
||||
diff.push(`missing ${file}`);
|
||||
} else if (left !== right) {
|
||||
diff.push(`changed ${file}`);
|
||||
}
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
function listFiles(root) {
|
||||
const files = new Map();
|
||||
if (!existsSync(root)) {
|
||||
return files;
|
||||
}
|
||||
walk(root, root, files);
|
||||
return files;
|
||||
}
|
||||
|
||||
function walk(root, dir, files) {
|
||||
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
||||
const path = join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
walk(root, path, files);
|
||||
} else if (entry.isFile()) {
|
||||
files.set(relative(root, path), sha256(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sha256(path) {
|
||||
return createHash("sha256").update(readFileSync(path)).digest("hex");
|
||||
}
|
||||
Reference in New Issue
Block a user