fix(skill): pin packaged commands to the shipping package version

The generated skill rewrote `rea-agents@latest` to the version it ships with, so a pinned install no longer needs a local edit that `doctor --skill` reports as stale.

Co-Authored-By: OpenCode <opencode@opencode.ai>
This commit is contained in:
Yi-111-aandOpenCode authored and morluto committed 2026-10-10 02:49:46 +08:00
1 parent 1ac8389c5c
commit 2793672ee2
3 files changed
+42 -7

No files matched your search

+14 -5
View File
@@ -16,8 +16,12 @@ const check = arguments_.has("--check");
const current = (
await readFile(join(sourceRoot, "SKILL.md"), "utf8")
).replaceAll("\r\n", "\n");
const cacheBust = String(Date.now());
const { CATALOG_IDENTITY } = await import(
`${pathToFileURL(join(root, "dist/catalogIdentity.js")).href}?${String(Date.now())}`
`${pathToFileURL(join(root, "dist/catalogIdentity.js")).href}?${cacheBust}`
);
const { PACKAGE_METADATA } = await import(
`${pathToFileURL(join(root, "dist/generatedPackageMetadata.js")).href}?${cacheBust}`
);
if (/^\s{2}(?:tool_count|catalog_digest):/mu.test(current))
throw new Error(
@@ -26,10 +30,15 @@ if (/^\s{2}(?:tool_count|catalog_digest):/mu.test(current))
const versionLine = /^ {2}version: "[^"\r\n]+"$/mu;
if (!versionLine.test(current))
throw new Error("Missing authored skill version");
const source = current.replace(
versionLine,
`$&\n tool_count: ${String(CATALOG_IDENTITY.counts.mcp_tools)}`,
);
// A shipped skill must run the version it ships with, not whatever `@latest` resolves to.
const latestSpecifier = `${PACKAGE_METADATA.name}@latest`;
const pinnedSpecifier = `${PACKAGE_METADATA.name}@${PACKAGE_METADATA.version}`;
const source = current
.replace(
versionLine,
`$&\n tool_count: ${String(CATALOG_IDENTITY.counts.mcp_tools)}`,
)
.replaceAll(latestSpecifier, pinnedSpecifier);
const paths = await filePaths(sourceRoot);
// Rebuild this owned output directory so removed references cannot survive a build.
if (!check) await rm(outputRoot, { recursive: true, force: true });
@@ -100,7 +100,7 @@ describe("dependency install freshness", () => {
it("checks installed dependencies before restoring a cached build", async () => {
const root = await createBuildCacheFixture();
const seeded = await runNpm(root, ["run", "build:cached"]);
expect(seeded.status, seeded.stderr).toBe(0);
expect(seeded.status, `${seeded.stdout}${seeded.stderr}`).toBe(0);
const rootLock = asRecord(
JSON.parse(await readFile(join(root, "package-lock.json"), "utf8")),
@@ -189,7 +189,13 @@ const createBuildCacheFixture = async (): Promise<string> => {
);
await writeFile(
join(root, "scripts/cache-fixture-build.mjs"),
'import { mkdir, writeFile } from "node:fs/promises"; await mkdir("dist", { recursive: true }); await writeFile("dist/cache-fixture.js", "built"); await writeFile("dist/catalogIdentity.js", "export const CATALOG_IDENTITY = { counts: { mcp_tools: 1 } };\\n");\n',
`import { mkdir, readFile, writeFile } from "node:fs/promises";
const { name, version } = JSON.parse(await readFile("package.json", "utf8"));
await mkdir("dist", { recursive: true });
await writeFile("dist/cache-fixture.js", "built");
await writeFile("dist/catalogIdentity.js", "export const CATALOG_IDENTITY = { counts: { mcp_tools: 1 } };\\n");
await writeFile("dist/generatedPackageMetadata.js", "export const PACKAGE_METADATA = " + JSON.stringify({ name, version }) + ";\\n");
`,
);
await createNodeModulesLinks(root);
await writeFile(
@@ -26,6 +26,10 @@ async function fixture(eol = "\n") {
await mkdir(join(sourceRoot, "references"), { recursive: true });
await mkdir(join(root, "dist"));
await writeFile(join(root, "package.json"), '{"type":"module"}\n');
await writeFile(
join(root, "dist/generatedPackageMetadata.js"),
'export const PACKAGE_METADATA = { name: "rea-agents", version: "6.2.0" };\n',
);
await writeFile(join(sourceRoot, "SKILL.md"), authored.replaceAll("\n", eol));
await writeFile(
join(sourceRoot, "references/guide.md"),
@@ -111,6 +115,22 @@ it("rejects missing, stale, and extra packaged references and removes deleted so
await f.generate("--check");
});
it("pins authored `@latest` commands to the packaged version", async () => {
const f = await fixture();
await writeFile(
join(f.sourceRoot, "SKILL.md"),
authored.replace(
"Inspect the caller-selected artifact.",
"Run `npx -y rea-agents@latest doctor --json` first.",
),
);
await f.generate();
const generated = await readFile(join(f.outputRoot, "SKILL.md"), "utf8");
expect(generated).toContain("npx -y rea-agents@6.2.0 doctor --json");
expect(generated).not.toContain("rea-agents@latest");
await f.generate("--check");
});
it("rejects catalog-dependent metadata in the authored source", async () => {
const f = await fixture();
await writeFile(