mirror of
https://github.com/luckyyzh/pi-agent-integrated.git
synced 2026-10-03 11:09:34 +00:00
183 lines
6.2 KiB
JavaScript
183 lines
6.2 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import test from "node:test";
|
|
import { createJiti } from "jiti";
|
|
|
|
const jiti = createJiti(import.meta.url);
|
|
const { annotateSkillsWithInstallInfo, getGlobalSkillsLockPath } =
|
|
await jiti.import("./skill-lock.ts");
|
|
|
|
function writeJson(path, value) {
|
|
writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`, "utf8");
|
|
}
|
|
|
|
function makeSkill(name, filePath, scope) {
|
|
return {
|
|
name,
|
|
description: `${name} description`,
|
|
filePath,
|
|
baseDir: filePath.slice(0, -"/SKILL.md".length),
|
|
disableModelInvocation: false,
|
|
sourceInfo: { scope },
|
|
};
|
|
}
|
|
|
|
test("uses the CLI global lock location", () => {
|
|
assert.equal(
|
|
getGlobalSkillsLockPath({ homeDir: "/home/test", xdgStateHome: undefined }),
|
|
join("/home/test", ".agents", ".skill-lock.json"),
|
|
);
|
|
assert.equal(
|
|
getGlobalSkillsLockPath({ homeDir: "/home/test", xdgStateHome: "/state" }),
|
|
join("/state", "skills", ".skill-lock.json"),
|
|
);
|
|
});
|
|
|
|
test("annotates only lock entries that exist in the matching Pi scope", () => {
|
|
const root = mkdtempSync(join(tmpdir(), "pi-web-skill-lock-"));
|
|
try {
|
|
const cwd = join(root, "project");
|
|
const agentDir = join(root, "home", ".pi", "agent");
|
|
const globalLockPath = join(root, "global-lock.json");
|
|
const projectLockPath = join(cwd, "skills-lock.json");
|
|
const globalSkillPath = join(agentDir, "skills", "edge-tts", "SKILL.md");
|
|
const projectSkillPath = join(cwd, ".pi", "skills", "find-skills", "SKILL.md");
|
|
const manualSkillPath = join(agentDir, "skills", "manual", "SKILL.md");
|
|
const otherAgentSkillPath = join(root, "other-agent", "tts", "SKILL.md");
|
|
|
|
for (const path of [globalSkillPath, projectSkillPath, manualSkillPath, otherAgentSkillPath]) {
|
|
mkdirSync(join(path, ".."), { recursive: true });
|
|
writeFileSync(path, "---\nname: test\n---\n", "utf8");
|
|
}
|
|
|
|
writeJson(globalLockPath, {
|
|
version: 3,
|
|
skills: {
|
|
"edge-tts": {
|
|
source: "https://github.com/aahl/skills.git",
|
|
sourceType: "github",
|
|
skillPath: "skills/edge-tts/SKILL.md",
|
|
skillFolderHash: "global-version",
|
|
},
|
|
tts: { source: "noizai/skills", sourceType: "github" },
|
|
},
|
|
});
|
|
writeJson(projectLockPath, {
|
|
version: 1,
|
|
skills: {
|
|
"find-skills": {
|
|
source: "vercel-labs/skills",
|
|
sourceType: "github",
|
|
skillPath: "skills/find-skills/SKILL.md",
|
|
computedHash: "project-version",
|
|
},
|
|
},
|
|
});
|
|
|
|
const annotated = annotateSkillsWithInstallInfo(
|
|
[
|
|
makeSkill("edge-tts", globalSkillPath, "user"),
|
|
makeSkill("find-skills", projectSkillPath, "project"),
|
|
makeSkill("manual", manualSkillPath, "user"),
|
|
makeSkill("tts", otherAgentSkillPath, "user"),
|
|
],
|
|
{ cwd, agentDir, globalLockPath, projectLockPath },
|
|
);
|
|
|
|
assert.deepEqual(annotated[0].install, {
|
|
package: "aahl/skills@edge-tts",
|
|
scope: "global",
|
|
source: "aahl/skills",
|
|
sourceType: "github",
|
|
skillsShUrl: "https://skills.sh/aahl/skills/edge-tts",
|
|
skillPath: "skills/edge-tts/SKILL.md",
|
|
versionHash: "global-version",
|
|
canCheckForUpdates: true,
|
|
});
|
|
assert.deepEqual(annotated[1].install, {
|
|
package: "vercel-labs/skills@find-skills",
|
|
scope: "project",
|
|
source: "vercel-labs/skills",
|
|
sourceType: "github",
|
|
skillsShUrl: "https://skills.sh/vercel-labs/skills/find-skills",
|
|
skillPath: "skills/find-skills/SKILL.md",
|
|
versionHash: "project-version",
|
|
canCheckForUpdates: true,
|
|
});
|
|
assert.equal(annotated[2].install, undefined);
|
|
assert.equal(annotated[3].install, undefined);
|
|
} finally {
|
|
rmSync(root, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
test("ignores stale lock entries and malformed lock files", () => {
|
|
const root = mkdtempSync(join(tmpdir(), "pi-web-skill-lock-"));
|
|
try {
|
|
const cwd = join(root, "project");
|
|
const agentDir = join(root, "agent");
|
|
const missingPath = join(agentDir, "skills", "missing", "SKILL.md");
|
|
const projectSkillPath = join(cwd, ".pi", "skills", "broken", "SKILL.md");
|
|
const globalLockPath = join(root, "global-lock.json");
|
|
const projectLockPath = join(root, "project-lock.json");
|
|
mkdirSync(join(projectSkillPath, ".."), { recursive: true });
|
|
writeFileSync(projectSkillPath, "---\nname: broken\n---\n", "utf8");
|
|
writeJson(globalLockPath, {
|
|
version: 3,
|
|
skills: {
|
|
missing: { source: "owner/repo", sourceType: "github" },
|
|
},
|
|
});
|
|
writeFileSync(projectLockPath, "not json", "utf8");
|
|
|
|
const skills = annotateSkillsWithInstallInfo(
|
|
[
|
|
makeSkill("missing", missingPath, "user"),
|
|
makeSkill("broken", projectSkillPath, "project"),
|
|
],
|
|
{ cwd, agentDir, globalLockPath, projectLockPath },
|
|
);
|
|
|
|
assert.equal(skills[0].install, undefined);
|
|
assert.equal(skills[1].install, undefined);
|
|
} finally {
|
|
rmSync(root, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
test("does not compare a project ref with the default skills.sh snapshot", () => {
|
|
const root = mkdtempSync(join(tmpdir(), "pi-web-skill-lock-"));
|
|
try {
|
|
const cwd = join(root, "project");
|
|
const agentDir = join(root, "agent");
|
|
const projectLockPath = join(cwd, "skills-lock.json");
|
|
const projectSkillPath = join(cwd, ".pi", "skills", "preview", "SKILL.md");
|
|
mkdirSync(join(projectSkillPath, ".."), { recursive: true });
|
|
writeFileSync(projectSkillPath, "---\nname: preview\n---\n", "utf8");
|
|
writeJson(projectLockPath, {
|
|
version: 1,
|
|
skills: {
|
|
preview: {
|
|
source: "owner/repo",
|
|
sourceType: "github",
|
|
skillPath: "skills/preview/SKILL.md",
|
|
ref: "preview",
|
|
computedHash: "project-version",
|
|
},
|
|
},
|
|
});
|
|
|
|
const [skill] = annotateSkillsWithInstallInfo(
|
|
[makeSkill("preview", projectSkillPath, "project")],
|
|
{ cwd, agentDir, projectLockPath, globalLockPath: join(root, "missing.json") },
|
|
);
|
|
|
|
assert.equal(skill.install.ref, "preview");
|
|
assert.equal(skill.install.canCheckForUpdates, false);
|
|
} finally {
|
|
rmSync(root, { recursive: true, force: true });
|
|
}
|
|
});
|