* fix: stabilize validation and tests on Windows * test: add Windows smoke coverage for skill activation * refactor: make setup_web script CommonJS * fix: repair aegisops-ai frontmatter * docs: add when-to-use guidance to core skills * docs: add when-to-use guidance to Apify skills * docs: add when-to-use guidance to Google and Expo skills * docs: add when-to-use guidance to Makepad skills * docs: add when-to-use guidance to git workflow skills * docs: add when-to-use guidance to fp-ts skills * docs: add when-to-use guidance to Three.js skills * docs: add when-to-use guidance to n8n skills * docs: add when-to-use guidance to health analysis skills * docs: add when-to-use guidance to writing and review skills * meta: sync generated catalog metadata * docs: add when-to-use guidance to Robius skills * docs: add when-to-use guidance to review and workflow skills * docs: add when-to-use guidance to science and data skills * docs: add when-to-use guidance to tooling and automation skills * docs: add when-to-use guidance to remaining skills * fix: gate bundle helper execution in Windows activation * chore: drop generated artifacts from contributor PR * docs(maintenance): Record PR 457 sweep Document the open issue triage, PR supersedence decision, local verification, and source-only cleanup that prepared PR #457 for re-running CI. --------- Co-authored-by: sickn33 <sickn33@users.noreply.github.com>
124 lines
4.1 KiB
JavaScript
124 lines
4.1 KiB
JavaScript
const assert = require("assert");
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const { spawnSync } = require("child_process");
|
|
|
|
if (process.platform !== "win32") {
|
|
console.log("Skipping activate-skills.bat smoke test outside Windows.");
|
|
process.exit(0);
|
|
}
|
|
|
|
const repoRoot = path.resolve(__dirname, "../..", "..");
|
|
const scriptPath = path.join("scripts", "activate-skills.bat");
|
|
const root = fs.mkdtempSync(path.join(repoRoot, ".tmp-activate-skills-batch-"));
|
|
const baseDir = path.join(root, "antigravity");
|
|
const repoSkills = path.join(root, "repo-skills");
|
|
|
|
function makeSkill(skillId) {
|
|
const skillDir = path.join(repoSkills, skillId);
|
|
fs.mkdirSync(skillDir, { recursive: true });
|
|
fs.writeFileSync(
|
|
path.join(skillDir, "SKILL.md"),
|
|
`---\nname: ${skillId}\ndescription: test skill\ncategory: testing\nrisk: safe\nsource: community\ndate_added: "2026-04-05"\n---\n`,
|
|
"utf8",
|
|
);
|
|
}
|
|
|
|
try {
|
|
makeSkill("brainstorming");
|
|
makeSkill("custom-skill");
|
|
fs.mkdirSync(path.join(baseDir, "skills", "legacy-skill"), { recursive: true });
|
|
fs.writeFileSync(path.join(baseDir, "skills", "legacy-skill", "SKILL.md"), "legacy", "utf8");
|
|
|
|
const result = spawnSync(
|
|
"cmd.exe",
|
|
["/d", "/c", `${scriptPath} --clear brainstorming custom-skill`],
|
|
{
|
|
cwd: repoRoot,
|
|
env: {
|
|
...process.env,
|
|
AG_BASE_DIR: baseDir,
|
|
AG_REPO_SKILLS_DIR: repoSkills,
|
|
AG_PYTHON_BIN: "__missing_python__",
|
|
AG_NO_PAUSE: "1",
|
|
},
|
|
encoding: "utf8",
|
|
timeout: 20000,
|
|
maxBuffer: 1024 * 1024 * 20,
|
|
},
|
|
);
|
|
|
|
if (result.error) {
|
|
if (result.error.code === "EPERM" || result.error.code === "EACCES") {
|
|
console.log("Skipping activate-skills.bat smoke test; this sandbox blocks cmd.exe child processes.");
|
|
process.exit(0);
|
|
}
|
|
throw result.error;
|
|
}
|
|
|
|
assert.strictEqual(result.status, 0, result.stderr || result.stdout);
|
|
assert.ok(
|
|
fs.existsSync(path.join(baseDir, "skills", "brainstorming", "SKILL.md")),
|
|
"brainstorming should be activated into the live skills directory",
|
|
);
|
|
assert.ok(
|
|
fs.existsSync(path.join(baseDir, "skills", "custom-skill", "SKILL.md")),
|
|
"custom-skill should be activated into the live skills directory",
|
|
);
|
|
assert.ok(
|
|
fs.existsSync(path.join(baseDir, "skills_library", "brainstorming", "SKILL.md")),
|
|
"repo skills should be synced into the backing library",
|
|
);
|
|
const archives = fs.readdirSync(baseDir).filter((entry) => entry.startsWith("skills_archive_"));
|
|
assert.ok(archives.length > 0, "--clear should archive the previously active skills directory");
|
|
assert.ok(
|
|
fs.existsSync(path.join(baseDir, archives[0], "legacy-skill", "SKILL.md")),
|
|
"legacy active skills should move into a timestamped archive",
|
|
);
|
|
assert.match(
|
|
result.stdout,
|
|
/Done! Antigravity skills are now activated\./,
|
|
"script should report successful activation",
|
|
);
|
|
|
|
const missingHelperBaseDir = path.join(root, "antigravity-missing-helper");
|
|
const missingHelperResult = spawnSync(
|
|
"cmd.exe",
|
|
["/d", "/c", `${scriptPath} --clear custom-skill`],
|
|
{
|
|
cwd: repoRoot,
|
|
env: {
|
|
...process.env,
|
|
AG_BASE_DIR: missingHelperBaseDir,
|
|
AG_REPO_SKILLS_DIR: repoSkills,
|
|
AG_BUNDLE_HELPER: path.join(root, "missing-bundle-helper.py"),
|
|
AG_PYTHON_BIN: "__missing_python__",
|
|
AG_NO_PAUSE: "1",
|
|
},
|
|
encoding: "utf8",
|
|
timeout: 20000,
|
|
maxBuffer: 1024 * 1024 * 20,
|
|
},
|
|
);
|
|
|
|
if (missingHelperResult.error) {
|
|
if (missingHelperResult.error.code === "EPERM" || missingHelperResult.error.code === "EACCES") {
|
|
console.log("Skipping activate-skills.bat smoke test; this sandbox blocks cmd.exe child processes.");
|
|
process.exit(0);
|
|
}
|
|
throw missingHelperResult.error;
|
|
}
|
|
|
|
assert.strictEqual(
|
|
missingHelperResult.status,
|
|
0,
|
|
missingHelperResult.stderr || missingHelperResult.stdout,
|
|
);
|
|
assert.ok(
|
|
fs.existsSync(path.join(missingHelperBaseDir, "skills", "custom-skill", "SKILL.md")),
|
|
"explicit skill args should still activate when the bundle helper path is missing",
|
|
);
|
|
} finally {
|
|
fs.rmSync(root, { recursive: true, force: true });
|
|
}
|