📦 deps(thirdparty): update snapshots

This commit is contained in:
ci[bot]
2026-06-01 02:53:39 +00:00
parent 54038462a6
commit 843ff9620b
152 changed files with 7539 additions and 822 deletions
@@ -5,7 +5,7 @@ const path = require("path");
const repoRoot = path.resolve(__dirname, "..", "..", "..");
function readText(relativePath) {
return fs.readFileSync(path.join(repoRoot, relativePath), "utf8");
return fs.readFileSync(path.join(repoRoot, relativePath), "utf8").replace(/\r\n/g, "\n");
}
const packageJson = JSON.parse(readText("package.json"));
@@ -5,6 +5,7 @@ const os = require("os");
const path = require("path");
const { copyRecursiveSync } = require("../../bin/install");
const { createSymlinkOrSkip } = require("./symlink-test-utils");
async function main() {
const { copyFolderSync, copyIndexFile } = await import("../../scripts/setup_web.js");
@@ -22,22 +23,31 @@ async function main() {
fs.writeFileSync(path.join(safeRoot, "nested", "ok.txt"), "ok");
fs.writeFileSync(path.join(outsideDir, "secret.txt"), "secret");
fs.writeFileSync(path.join(outsideDir, "symlink-secret.txt"), "do-not-touch");
fs.symlinkSync(path.join(outsideDir, "symlink-secret.txt"), symlinkDestination);
fs.symlinkSync(outsideDir, path.join(safeRoot, "escape-link"));
const createdSymlinkDestination = createSymlinkOrSkip(
path.join(outsideDir, "symlink-secret.txt"),
symlinkDestination,
);
const createdEscapeLink = createSymlinkOrSkip(
outsideDir,
path.join(safeRoot, "escape-link"),
"dir",
);
copyRecursiveSync(safeRoot, path.join(destRoot, "install-copy"), safeRoot);
copyFolderSync(safeRoot, path.join(destRoot, "web-copy"), safeRoot);
assert.strictEqual(
fs.existsSync(path.join(destRoot, "install-copy", "escape-link", "secret.txt")),
false,
"installer copy must not follow symlinks outside the cloned root",
);
assert.strictEqual(
fs.existsSync(path.join(destRoot, "web-copy", "escape-link", "secret.txt")),
false,
"web setup copy must not follow symlinks outside the skills root",
);
if (createdEscapeLink) {
assert.strictEqual(
fs.existsSync(path.join(destRoot, "install-copy", "escape-link", "secret.txt")),
false,
"installer copy must not follow symlinks outside the cloned root",
);
assert.strictEqual(
fs.existsSync(path.join(destRoot, "web-copy", "escape-link", "secret.txt")),
false,
"web setup copy must not follow symlinks outside the skills root",
);
}
assert.strictEqual(
fs.readFileSync(path.join(destRoot, "install-copy", "nested", "ok.txt"), "utf8"),
"ok",
@@ -46,34 +56,38 @@ async function main() {
fs.readFileSync(path.join(destRoot, "web-copy", "nested", "ok.txt"), "utf8"),
"ok",
);
assert.throws(
() =>
copyRecursiveSync(
path.join(safeRoot, "nested", "ok.txt"),
symlinkDestination,
safeRoot,
),
/Skipping unsafe destination symlink/i,
"installer copy should refuse writing into existing destination symlinks",
);
assert.strictEqual(
fs.readFileSync(path.join(outsideDir, "symlink-secret.txt"), "utf8"),
"do-not-touch",
);
if (createdSymlinkDestination) {
assert.throws(
() =>
copyRecursiveSync(
path.join(safeRoot, "nested", "ok.txt"),
symlinkDestination,
safeRoot,
),
/Skipping unsafe destination symlink/i,
"installer copy should refuse writing into existing destination symlinks",
);
assert.strictEqual(
fs.readFileSync(path.join(outsideDir, "symlink-secret.txt"), "utf8"),
"do-not-touch",
);
}
const indexSource = path.join(root, "skills_index.json");
const outsideIndexTarget = path.join(outsideDir, "index-target.json");
const symlinkedIndexDest = path.join(destRoot, "skills.json");
fs.writeFileSync(indexSource, "[]");
fs.writeFileSync(outsideIndexTarget, "outside");
fs.symlinkSync(outsideIndexTarget, symlinkedIndexDest);
const createdIndexSymlink = createSymlinkOrSkip(outsideIndexTarget, symlinkedIndexDest);
assert.throws(
() => copyIndexFile(indexSource, symlinkedIndexDest),
/symlink/i,
"web setup index copy must reject destination symlinks",
);
assert.strictEqual(fs.readFileSync(outsideIndexTarget, "utf8"), "outside");
if (createdIndexSymlink) {
assert.throws(
() => copyIndexFile(indexSource, symlinkedIndexDest),
/symlink/i,
"web setup index copy must reject destination symlinks",
);
assert.strictEqual(fs.readFileSync(outsideIndexTarget, "utf8"), "outside");
}
const repoRoot = path.resolve(__dirname, "..", "..", "..");
const repoTmp = path.join(repoRoot, ".tmp", `copy-security-${process.pid}`);
@@ -83,25 +97,27 @@ async function main() {
fs.mkdirSync(repoTmp, { recursive: true });
fs.writeFileSync(copySource, "new content");
fs.writeFileSync(outsideCopyTarget, "outside");
fs.symlinkSync(outsideCopyTarget, copyDest);
const createdCopyDestSymlink = createSymlinkOrSkip(outsideCopyTarget, copyDest);
const copyResult = spawnSync(
process.execPath,
[
path.join(repoRoot, "tools", "scripts", "copy-file.js"),
path.relative(repoRoot, copySource),
path.relative(repoRoot, copyDest),
],
{ cwd: repoRoot, encoding: "utf8" },
);
if (createdCopyDestSymlink) {
const copyResult = spawnSync(
process.execPath,
[
path.join(repoRoot, "tools", "scripts", "copy-file.js"),
path.relative(repoRoot, copySource),
path.relative(repoRoot, copyDest),
],
{ cwd: repoRoot, encoding: "utf8" },
);
assert.notStrictEqual(copyResult.status, 0, "copy-file must fail for destination symlinks");
assert.match(
`${copyResult.stdout}\n${copyResult.stderr}`,
/symlink/i,
"copy-file failure should explain that symlink destinations are refused",
);
assert.strictEqual(fs.readFileSync(outsideCopyTarget, "utf8"), "outside");
assert.notStrictEqual(copyResult.status, 0, "copy-file must fail for destination symlinks");
assert.match(
`${copyResult.stdout}\n${copyResult.stderr}`,
/symlink/i,
"copy-file failure should explain that symlink destinations are refused",
);
assert.strictEqual(fs.readFileSync(outsideCopyTarget, "utf8"), "outside");
}
fs.rmSync(repoTmp, { recursive: true, force: true });
} finally {
fs.rmSync(root, { recursive: true, force: true });
@@ -1,4 +1,6 @@
const assert = require("assert");
const fs = require("fs");
const os = require("os");
const path = require("path");
const installer = require(path.resolve(__dirname, "..", "..", "bin", "install.js"));
@@ -61,6 +63,19 @@ assert.ok(
antigravityMessages.some((message) => message.includes("activate-skills.bat")),
"Antigravity installs should mention the Windows activation flow",
);
assert.ok(
antigravityMessages.some((message) => message.includes("--agy")),
"Antigravity installs should point agy CLI users to the flat CLI layout",
);
const agyMessages = installer.getPostInstallMessages([
{ name: "Antigravity CLI", path: "/tmp/.gemini/antigravity-cli/skills", layout: "flat-markdown" },
]);
assert.ok(
agyMessages.some((message) => message.includes("/skills")),
"Antigravity CLI installs should tell users how to verify slash commands",
);
const codexMessages = installer.getPostInstallMessages([
{ name: "Codex CLI", path: "/tmp/.codex/skills" },
@@ -71,3 +86,44 @@ assert.strictEqual(
false,
"Non-Antigravity installs should not emit the Antigravity-specific overload hint",
);
const fixtureRoot = fs.mkdtempSync(path.join(os.tmpdir(), "agy-install-fixture-"));
try {
const tempDir = path.join(fixtureRoot, "repo");
const targetDir = path.join(fixtureRoot, "agy-skills");
const alphaDir = path.join(tempDir, "skills", "alpha");
const nestedDir = path.join(tempDir, "skills", "security", "audit");
fs.mkdirSync(alphaDir, { recursive: true });
fs.mkdirSync(nestedDir, { recursive: true });
fs.mkdirSync(targetDir, { recursive: true });
fs.writeFileSync(path.join(alphaDir, "SKILL.md"), "---\nname: alpha\n---\n\n# Alpha\n", "utf8");
fs.writeFileSync(path.join(nestedDir, "SKILL.md"), "---\nname: audit\n---\n\n# Audit\n", "utf8");
assert.deepStrictEqual(
installer.getManagedEntries(["alpha", "security/audit", "docs"], { layout: "flat-markdown" }),
["alpha.md", "audit.md"],
"agy CLI flat installs should track markdown skill files instead of skill directories",
);
installer.installSkillsIntoFlatMarkdownTarget(tempDir, targetDir, [
"alpha",
"security/audit",
"docs",
]);
assert.strictEqual(
fs.readFileSync(path.join(targetDir, "alpha.md"), "utf8"),
"---\nname: alpha\n---\n\n# Alpha\n",
);
assert.strictEqual(
fs.readFileSync(path.join(targetDir, "audit.md"), "utf8"),
"---\nname: audit\n---\n\n# Audit\n",
);
assert.strictEqual(
fs.existsSync(path.join(targetDir, "docs")),
false,
"agy CLI flat installs should not copy docs as a slash-command entry",
);
} finally {
fs.rmSync(fixtureRoot, { recursive: true, force: true });
}
@@ -4,6 +4,7 @@ const os = require("os");
const path = require("path");
const { spawnSync } = require("child_process");
const { createSymlinkOrSkip } = require("./symlink-test-utils");
const installer = require(path.resolve(__dirname, "..", "..", "bin", "install.js"));
function writeSkill(repoRoot, skillName, content = "# Skill\n") {
@@ -143,7 +144,10 @@ installer.installForTarget(${JSON.stringify(repoV2)}, { name: "BadTarget", path:
const symlinkRealTarget = path.join(tmpRoot, "symlink-real-target");
const symlinkTargetPath = path.join(tmpRoot, "symlink-target");
fs.mkdirSync(path.join(symlinkRealTarget, ".git"), { recursive: true });
fs.symlinkSync(symlinkRealTarget, symlinkTargetPath, "dir");
const createdSymlinkTarget = createSymlinkOrSkip(symlinkRealTarget, symlinkTargetPath, "dir");
if (!createdSymlinkTarget) {
return;
}
const symlinkTargetCheck = spawnSync(
process.execPath,
@@ -3,6 +3,8 @@ const fs = require("fs");
const os = require("os");
const path = require("path");
const { createSymlinkOrSkip } = require("./symlink-test-utils");
async function main() {
const repoRoot = path.resolve(__dirname, "..", "..", "..");
const loaderPath = path.join(
@@ -111,18 +113,20 @@ async function main() {
fs.mkdirSync(symlinkedDir, { recursive: true });
fs.mkdirSync(outsideDir, { recursive: true });
fs.writeFileSync(path.join(outsideDir, "secret.md"), "# secret\n", "utf8");
fs.symlinkSync(
const createdSymlink = createSymlinkOrSkip(
path.join(outsideDir, "secret.md"),
path.join(symlinkedDir, "SKILL.md"),
);
await assert.rejects(
() =>
loadSkillBodies(fixtureRoot, [
{ id: "symlinked", path: "skills/symlinked", name: "symlinked" },
]),
/symlink|outside the skills root|regular file/i,
);
if (createdSymlink) {
await assert.rejects(
() =>
loadSkillBodies(fixtureRoot, [
{ id: "symlinked", path: "skills/symlinked", name: "symlinked" },
]),
/symlink|outside the skills root|regular file/i,
);
}
console.log("✅ All Jetski Loader Security Checks Passed!");
} finally {
fs.rmSync(fixtureRoot, { recursive: true, force: true });
@@ -4,6 +4,8 @@ const fs = require("fs");
const os = require("os");
const path = require("path");
const { createSymlinkOrSkip } = require("./symlink-test-utils");
const repoRoot = path.resolve(__dirname, "../..", "..");
const pycacheDir = path.join(repoRoot, "skills", "ui-ux-pro-max", "scripts", "__pycache__");
const nestedSkillsDir = path.join(repoRoot, "skills", "skills");
@@ -41,7 +43,12 @@ assert.doesNotMatch(alphaVantage, /--- Unknown/, "alpha-vantage frontmatter shou
"[absolute](/etc/passwd)\n[traversal](../../etc/passwd)\n[symlink](linked-secret)\n[missing](docs/missing.md)\n",
"utf8",
);
fs.symlinkSync("/etc/passwd", path.join(targetRepo, "linked-secret"));
const outsideSecret = path.join(tempDir, "outside-secret");
fs.writeFileSync(outsideSecret, "secret", "utf8");
const createdSymlink = createSymlinkOrSkip(outsideSecret, path.join(targetRepo, "linked-secret"));
if (!createdSymlink) {
return;
}
const fakeBin = path.join(tempDir, "bin");
fs.mkdirSync(fakeBin);
const fakeRg = path.join(fakeBin, "rg");
@@ -4,6 +4,7 @@ const os = require("os");
const path = require("path");
const { listSkillIds, listSkillIdsRecursive, readSkill } = require("../../lib/skill-utils");
const { createSymlinkOrSkip } = require("./symlink-test-utils");
function withTempDir(fn) {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "skill-utils-security-"));
@@ -25,7 +26,10 @@ withTempDir((root) => {
fs.writeFileSync(path.join(skillsDir, "safe-skill", "SKILL.md"), "# safe\n");
fs.writeFileSync(path.join(outsideDir, "SKILL.md"), "# secret\n");
fs.symlinkSync(outsideDir, path.join(skillsDir, "linked-secret"));
const createdSymlink = createSymlinkOrSkip(outsideDir, path.join(skillsDir, "linked-secret"), "dir");
if (!createdSymlink) {
return;
}
const skillIds = listSkillIds(skillsDir);
@@ -47,7 +51,14 @@ withTempDir((root) => {
fs.writeFileSync(path.join(skillsDir, "nested", "safe-skill", "SKILL.md"), "# safe\n");
fs.mkdirSync(path.join(outsideDir, "loop-target"), { recursive: true });
fs.symlinkSync(outsideDir, path.join(skillsDir, "nested", "linked-secret"));
const createdSymlink = createSymlinkOrSkip(
outsideDir,
path.join(skillsDir, "nested", "linked-secret"),
"dir",
);
if (!createdSymlink) {
return;
}
const skillIds = listSkillIdsRecursive(skillsDir);
@@ -0,0 +1,29 @@
const fs = require("fs");
function isSymlinkPrivilegeError(error) {
return (
error &&
(error.code === "EPERM" ||
error.code === "EACCES" ||
error.errno === -4048 ||
/privilege|WinError 1314/i.test(String(error.message || "")))
);
}
function createSymlinkOrSkip(target, linkPath, type) {
try {
fs.symlinkSync(target, linkPath, type);
return true;
} catch (error) {
if (process.platform === "win32" && isSymlinkPrivilegeError(error)) {
console.warn(`[tests] Skipping symlink assertion; Windows denied symlink creation: ${linkPath}`);
return false;
}
throw error;
}
}
module.exports = {
createSymlinkOrSkip,
isSymlinkPrivilegeError,
};
@@ -4,6 +4,7 @@ const os = require("os");
const path = require("path");
const { resolveSafeRealPath } = require("../../lib/symlink-safety");
const { createSymlinkOrSkip } = require("./symlink-test-utils");
function withTempDir(fn) {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "symlink-safety-"));
@@ -26,8 +27,11 @@ withTempDir((root) => {
fs.writeFileSync(path.join(internalDir, "data.txt"), "ok");
fs.writeFileSync(path.join(outsideDir, "secret.txt"), "secret");
fs.symlinkSync(internalDir, internalLink);
fs.symlinkSync(outsideDir, outsideLink);
const createdInternalLink = createSymlinkOrSkip(internalDir, internalLink, "dir");
const createdOutsideLink = createSymlinkOrSkip(outsideDir, outsideLink, "dir");
if (!createdInternalLink || !createdOutsideLink) {
return;
}
const internalResolved = resolveSafeRealPath(safeRoot, internalLink);
const outsideResolved = resolveSafeRealPath(safeRoot, outsideLink);
@@ -0,0 +1,24 @@
import errno
import os
import unittest
def is_symlink_privilege_error(error: OSError) -> bool:
winerror = getattr(error, "winerror", None)
return (
os.name == "nt"
and (
winerror == 1314
or error.errno in {errno.EPERM, errno.EACCES}
or "privilege" in str(error).lower()
)
)
def symlink_or_skip(test_case: unittest.TestCase, target, link_path, target_is_directory=False) -> None:
try:
link_path.symlink_to(target, target_is_directory=target_is_directory)
except OSError as error:
if is_symlink_privilege_error(error):
test_case.skipTest(f"Windows denied symlink creation for {link_path}")
raise
@@ -6,6 +6,8 @@ import unittest
from pathlib import Path
from unittest import mock
from symlink_test_utils import symlink_or_skip
REPO_ROOT = Path(__file__).resolve().parents[3]
TOOLS_SCRIPTS_DIR = REPO_ROOT / "tools" / "scripts"
@@ -175,7 +177,7 @@ description: Build and distribute Expo development clients locally or via TestFl
"""
target.write_text(original, encoding="utf-8")
skill_path = skill_dir / "SKILL.md"
skill_path.symlink_to(target)
symlink_or_skip(self, target, skill_path)
changed, changes = cleanup_synthetic_skill_sections.cleanup_skill_file(repo_root, skill_path)
@@ -10,6 +10,8 @@ TOOLS_SCRIPTS_DIR = REPO_ROOT / "tools" / "scripts"
if str(TOOLS_SCRIPTS_DIR) not in sys.path:
sys.path.insert(0, str(TOOLS_SCRIPTS_DIR))
from symlink_test_utils import symlink_or_skip
def load_module(relative_path: str, module_name: str):
module_path = REPO_ROOT / relative_path
@@ -155,7 +157,7 @@ description: "External file."
"""
target.write_text(original, encoding="utf-8")
skill_path = skill_dir / "SKILL.md"
skill_path.symlink_to(target)
symlink_or_skip(self, target, skill_path)
changed, changes = fix_missing_skill_metadata.update_skill_file(skill_path)
@@ -10,6 +10,8 @@ TOOLS_SCRIPTS_DIR = REPO_ROOT / "tools" / "scripts"
if str(TOOLS_SCRIPTS_DIR) not in sys.path:
sys.path.insert(0, str(TOOLS_SCRIPTS_DIR))
from symlink_test_utils import symlink_or_skip
def load_module(relative_path: str, module_name: str):
module_path = REPO_ROOT / relative_path
@@ -144,7 +146,7 @@ description: Demo description.
"""
target.write_text(original, encoding="utf-8")
skill_path = skill_dir / "SKILL.md"
skill_path.symlink_to(target)
symlink_or_skip(self, target, skill_path)
changed, changes = fix_missing_skill_sections.update_skill_file(skill_path, add_missing=True)
@@ -8,6 +8,8 @@ TOOLS_SCRIPTS_DIR = Path(__file__).resolve().parents[1]
if str(TOOLS_SCRIPTS_DIR) not in sys.path:
sys.path.insert(0, str(TOOLS_SCRIPTS_DIR))
from symlink_test_utils import symlink_or_skip
import fix_skills_metadata
@@ -22,7 +24,7 @@ class FixSkillsMetadataSecurityTests(unittest.TestCase):
target = outside_dir / "SKILL.md"
target.write_text("---\nname: outside\n---\nbody\n", encoding="utf-8")
(skill_dir / "SKILL.md").symlink_to(target)
symlink_or_skip(self, target, skill_dir / "SKILL.md")
fix_skills_metadata.fix_skills(root)
@@ -10,6 +10,8 @@ TOOLS_SCRIPTS_DIR = REPO_ROOT / "tools" / "scripts"
if str(TOOLS_SCRIPTS_DIR) not in sys.path:
sys.path.insert(0, str(TOOLS_SCRIPTS_DIR))
from symlink_test_utils import symlink_or_skip
def load_module(relative_path: str, module_name: str):
module_path = REPO_ROOT / relative_path
@@ -127,7 +129,7 @@ This paragraph should never be written back through a symlink.
"""
target.write_text(original, encoding="utf-8")
skill_path = skill_dir / "SKILL.md"
skill_path.symlink_to(target)
symlink_or_skip(self, target, skill_path)
changed, new_description = fix_truncated_descriptions.update_skill_file(skill_path)
@@ -10,6 +10,8 @@ TOOLS_SCRIPTS_DIR = REPO_ROOT / "tools" / "scripts"
if str(TOOLS_SCRIPTS_DIR) not in sys.path:
sys.path.insert(0, str(TOOLS_SCRIPTS_DIR))
from symlink_test_utils import symlink_or_skip
def load_module(relative_path: str, module_name: str):
module_path = REPO_ROOT / relative_path
@@ -128,7 +130,7 @@ class FrontmatterParsingSecurityTests(unittest.TestCase):
(safe_skill / "SKILL.md").write_text("---\nname: safe-skill\ndescription: safe\n---\n", encoding="utf-8")
target = outside_dir / "SKILL.md"
target.write_text("---\nname: outside\ndescription: outside\n---\n", encoding="utf-8")
(linked_skill / "SKILL.md").symlink_to(target)
symlink_or_skip(self, target, linked_skill / "SKILL.md")
skills = generate_index.generate_index(str(skills_dir), str(output_file))
@@ -9,6 +9,8 @@ import unittest
REPO_ROOT = pathlib.Path(__file__).resolve().parents[3]
sys.path.insert(0, str(REPO_ROOT / "tools" / "scripts"))
from symlink_test_utils import symlink_or_skip
def load_module(module_path: str, module_name: str):
spec = importlib.util.spec_from_file_location(module_name, REPO_ROOT / module_path)
@@ -40,7 +42,7 @@ class GenerateIndexSecurityTests(unittest.TestCase):
(safe_skill_dir / "SKILL.md").write_text("---\nname: Safe Skill\n---\nbody\n", encoding="utf-8")
target = outside_dir / "secret.txt"
target.write_text("outside data", encoding="utf-8")
(linked_skill_dir / "SKILL.md").symlink_to(target)
symlink_or_skip(self, target, linked_skill_dir / "SKILL.md")
skills = generate_index.generate_index(str(skills_dir), str(output_file))
@@ -8,6 +8,8 @@ TOOLS_SCRIPTS_DIR = Path(__file__).resolve().parents[1]
if str(TOOLS_SCRIPTS_DIR) not in sys.path:
sys.path.insert(0, str(TOOLS_SCRIPTS_DIR))
from symlink_test_utils import symlink_or_skip
import sync_microsoft_skills as sms
@@ -25,12 +27,12 @@ class SyncMicrosoftSkillsSecurityTests(unittest.TestCase):
safe_skill = root / ".github" / "skills" / "safe-skill"
safe_skill.mkdir(parents=True)
(safe_skill / "SKILL.md").write_text("---\nname: safe-skill\n---\n", encoding="utf-8")
(skills_dir / "safe-skill").symlink_to(safe_skill, target_is_directory=True)
symlink_or_skip(self, safe_skill, skills_dir / "safe-skill", target_is_directory=True)
outside = Path(tempfile.mkdtemp())
try:
(outside / "SKILL.md").write_text("---\nname: leaked\n---\n", encoding="utf-8")
(skills_dir / "escape").symlink_to(outside, target_is_directory=True)
symlink_or_skip(self, outside, skills_dir / "escape", target_is_directory=True)
entries = sms.find_skills_in_directory(root)
relative_paths = {str(entry["relative_path"]) for entry in entries}
@@ -58,7 +60,7 @@ class SyncMicrosoftSkillsSecurityTests(unittest.TestCase):
try:
target = outside / "SKILL.md"
target.write_text("---\nname: escaped\n---\n", encoding="utf-8")
(linked_skill / "SKILL.md").symlink_to(target)
symlink_or_skip(self, target, linked_skill / "SKILL.md")
entries = sms.find_skills_in_directory(root)
relative_paths = {str(entry["relative_path"]) for entry in entries}
@@ -83,7 +85,7 @@ class SyncMicrosoftSkillsSecurityTests(unittest.TestCase):
escaped = outside / "escaped-skill"
escaped.mkdir()
(escaped / "SKILL.md").write_text("---\nname: escaped\n---\n", encoding="utf-8")
(github_skills / "escape").symlink_to(escaped, target_is_directory=True)
symlink_or_skip(self, escaped, github_skills / "escape", target_is_directory=True)
entries = sms.find_github_skills(root, set())
relative_paths = {str(entry["relative_path"]) for entry in entries}
@@ -112,7 +114,7 @@ class SyncMicrosoftSkillsSecurityTests(unittest.TestCase):
try:
target = outside / "SKILL.md"
target.write_text("---\nname: escaped\n---\n", encoding="utf-8")
(linked_skill / "SKILL.md").symlink_to(target)
symlink_or_skip(self, target, linked_skill / "SKILL.md")
entries = sms.find_github_skills(root, set())
relative_paths = {str(entry["relative_path"]) for entry in entries}
@@ -139,7 +141,7 @@ class SyncMicrosoftSkillsSecurityTests(unittest.TestCase):
try:
target = outside / "SKILL.md"
target.write_text("---\nname: escaped\n---\n", encoding="utf-8")
(linked_plugin / "SKILL.md").symlink_to(target)
symlink_or_skip(self, target, linked_plugin / "SKILL.md")
entries = sms.find_plugin_skills(root, set())
relative_paths = {str(entry["relative_path"]) for entry in entries}
@@ -158,7 +160,7 @@ class SyncMicrosoftSkillsSecurityTests(unittest.TestCase):
outside = root / "outside-license.txt"
outside.write_text("secret license payload", encoding="utf-8")
(source / "LICENSE").symlink_to(outside)
symlink_or_skip(self, outside, source / "LICENSE")
previous_docs_dir = sms.DOCS_DIR
sms.DOCS_DIR = docs
@@ -10,6 +10,8 @@ TOOLS_SCRIPTS_DIR = REPO_ROOT / "tools" / "scripts"
if str(TOOLS_SCRIPTS_DIR) not in sys.path:
sys.path.insert(0, str(TOOLS_SCRIPTS_DIR))
from symlink_test_utils import symlink_or_skip
def load_module(relative_path: str, module_name: str):
module_path = REPO_ROOT / relative_path
@@ -165,7 +167,7 @@ If you want a faster answer than "browse all 1,273+ skills", start with a tool-s
outside = root / "outside.md"
outside.write_text("original", encoding="utf-8")
linked = root / "README.md"
linked.symlink_to(outside)
symlink_or_skip(self, outside, linked)
changed = sync_repo_metadata.update_text_file(
linked,
@@ -7,6 +7,8 @@ import types
import unittest
from pathlib import Path
from symlink_test_utils import symlink_or_skip
REPO_ROOT = Path(__file__).resolve().parents[3]
MODULE_PATH = REPO_ROOT / "skills" / "videodb" / "scripts" / "ws_listener.py"
@@ -47,7 +49,7 @@ class WsListenerSecurityTests(unittest.TestCase):
module.OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
outside = state_home / "outside.txt"
outside.write_text("secret", encoding="utf-8")
module.PID_FILE.symlink_to(outside)
symlink_or_skip(self, outside, module.PID_FILE)
with self.assertRaises(OSError):
module.write_pid()
@@ -73,7 +75,7 @@ class WsListenerSecurityTests(unittest.TestCase):
module.OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
outside = state_home / "outside.jsonl"
outside.write_text("secret\n", encoding="utf-8")
module.EVENTS_FILE.symlink_to(outside)
symlink_or_skip(self, outside, module.EVENTS_FILE)
with self.assertRaises(OSError):
module.append_event({"channel": "demo"})