46 lines
1.9 KiB
JavaScript
46 lines
1.9 KiB
JavaScript
import { strict as assert } from "node:assert";
|
|||
|
|
import { test } from "node:test";
|
||
|
|
import { mkdtempSync, readFileSync, readdirSync, rmSync, symlinkSync } from "node:fs";
|
||
|
|
import { spawnSync } from "node:child_process";
|
||
|
|
import { dirname, join, relative, resolve } from "node:path";
|
||
|
|
import { tmpdir } from "node:os";
|
||
|
|
import { fileURLToPath } from "node:url";
|
||
|
|
|
||
|
|
const SKILLS = resolve(dirname(fileURLToPath(import.meta.url)), "../../..");
|
||
|
|
const CLI_MEDIA_USE = resolve(SKILLS, "../packages/cli/src/media-use");
|
||
|
|
|
||
|
|
// Agents install skills by symlinking the skills dir, so each script must still run its CLI.
|
||
|
|
test("skill CLIs run when invoked through a symlinked skills dir", () => {
|
||
|
|
const dir = mkdtempSync(join(tmpdir(), "skills-link-"));
|
||
|
|
try {
|
||
|
|
symlinkSync(SKILLS, join(dir, "skills"), "dir");
|
||
|
|
for (const script of ["media-use/audio/scripts/heygen-voice.mjs"]) {
|
||
|
|
const run = spawnSync(process.execPath, [join(dir, "skills", script), "not-a-command"], {
|
||
|
|
encoding: "utf8",
|
||
|
|
});
|
||
|
|
assert.notEqual(run.status, 0, `${script} exited ${run.status} without running its CLI`);
|
||
|
|
assert.match(run.stderr, /usage/, script);
|
||
|
|
}
|
||
|
|
} finally {
|
||
|
|
rmSync(dir, { recursive: true, force: true });
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
function skillScripts(dir) {
|
||
|
|
return readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
|
||
|
|
const path = join(dir, entry.name);
|
||
|
|
if (entry.isDirectory()) return entry.name === "node_modules" ? [] : skillScripts(path);
|
||
|
|
return /\.(mjs|js)$/.test(entry.name) && !/\.test\.mjs$/.test(entry.name) ? [path] : [];
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
test("skill scripts detect their CLI entry through lib/main-module.mjs only", () => {
|
||
|
|
const handRolled = [...skillScripts(SKILLS), ...skillScripts(CLI_MEDIA_USE)].filter(
|
||
|
|
(path) =>
|
||
|
|
!path.endsWith("main-module.mjs") && readFileSync(path, "utf8").includes("process.argv[1]"),
|
||
|
|
);
|
||
|
|
assert.deepEqual(
|
||
|
|
handRolled.map((path) => relative(SKILLS, path)),
|
||
|
|
[],
|
||
|
|
);
|
||
|
|
});
|