Files
morluto d9660eb032 fix(verifiers): share package command and workspace ownership
Join canonical owned command cleanup before releasing package verifier workspaces. Replace raw package command wrappers, the updater supervisor, WASM cleanup composite, and boolean-only retention with explicit capability ownership.

Preserve selected environments, npm arguments, no-deadline calls, clean exit status, and distinct aggregate/per-stream output budgets. Exercise actual timeout descendants, cancellation, retained cleanup retry, and workspace admission.
2026-10-24 16:58:18 +08:00

117 lines
3.8 KiB
JavaScript

import { cp, mkdir, readFile, readdir } from "node:fs/promises";
import { dirname, join, relative } from "node:path";
import { pathExists } from "./lib/verify-package-core.mjs";
/** Install the separately locked Skills CLI so verification resolves no registry metadata. */
const lockedSkillsCli = async (commands, root, workspace) => {
const tool = join(workspace, "skills-cli");
await mkdir(tool, { recursive: true });
for (const file of ["package.json", "package-lock.json"])
await cp(join(root, "scripts/verify-tools/skills", file), join(tool, file));
await commands.execNpm(
["ci", "--prefer-offline", "--ignore-scripts", "--no-audit", "--no-fund"],
{ cwd: tool, timeout: 120_000 },
);
const installed = join(tool, "node_modules/skills");
const manifest = JSON.parse(
await readFile(join(installed, "package.json"), "utf8"),
);
return {
version: manifest.version,
entry: join(installed, manifest.bin.skills),
};
};
/** Exercise Skills' default root discovery without ignored build outputs. */
export async function verifyRepositorySkill({ root, workspace, commands }) {
const snapshot = join(workspace, "repository");
const consumer = join(workspace, "skill-consumer");
const home = join(workspace, "skill-consumer-home");
const tracked = (
await commands.exec(
"git",
["ls-files", "--cached", "--format=%(objectmode) %(path)", "-z"],
{ cwd: root },
)
).stdout
.split("\0")
.filter(Boolean);
for (const entry of tracked) {
const mode = entry.slice(0, 6);
const path = entry.slice(7);
const destination = join(snapshot, path);
// A GitHub clone without submodule initialization has only these directories.
if (mode === "160000") {
await mkdir(destination, { recursive: true });
continue;
}
await mkdir(dirname(destination), { recursive: true });
await cp(join(root, path), destination, { verbatimSymlinks: true });
}
if (await pathExists(join(snapshot, "skills")))
throw new Error("repository skill check must run without generated skills");
await mkdir(consumer, { recursive: true });
await mkdir(home, { recursive: true });
const { version: skillsVersion, entry } = await lockedSkillsCli(
commands,
root,
workspace,
);
await commands.exec(
process.execPath,
[
entry,
"add",
snapshot,
"--skill",
"reverse-engineer-anything",
"--agent",
"codex",
"--yes",
],
{
cwd: consumer,
env: {
...process.env,
HOME: home,
USERPROFILE: home,
XDG_CONFIG_HOME: join(home, ".config"),
CODEX_HOME: join(home, ".codex"),
DO_NOT_TRACK: "1",
SKILLS_NO_TELEMETRY: "1",
CI: "1",
},
timeout: 120_000,
},
);
const authoredRoot = join(
snapshot,
".agents/skills/reverse-engineer-anything",
);
const installedSkills = join(consumer, ".agents/skills");
const installedRoot = join(installedSkills, "reverse-engineer-anything");
const files = await filePaths(authoredRoot);
if (
JSON.stringify(await readdir(installedSkills)) !==
JSON.stringify(["reverse-engineer-anything"]) ||
JSON.stringify(await filePaths(installedRoot)) !== JSON.stringify(files)
)
throw new Error(
"Skills did not install exactly the selected public bundle",
);
for (const path of files) {
const authored = await readFile(join(authoredRoot, path));
if (!authored.equals(await readFile(join(installedRoot, path))))
throw new Error(`Skills changed authored skill content: ${path}`);
}
return { skillsVersion, files };
}
async function filePaths(root) {
return (await readdir(root, { recursive: true, withFileTypes: true }))
.filter((entry) => entry.isFile())
.map((entry) => relative(root, join(entry.parentPath, entry.name)))
.sort();
}