mirror of
https://github.com/luckyyzh/pi-agent-integrated.git
synced 2026-10-03 02:59:35 +00:00
183 lines
5.1 KiB
JavaScript
183 lines
5.1 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import { createJiti } from "jiti";
|
|
|
|
const jiti = createJiti(import.meta.url);
|
|
const {
|
|
buildSkillUpdateArgs,
|
|
checkSkillUpdate,
|
|
checkSkillUpdates,
|
|
skillUpdateKey,
|
|
} = await jiti.import("./skill-updates.ts");
|
|
|
|
function install(overrides = {}) {
|
|
return {
|
|
package: "owner/repo@example-skill",
|
|
scope: "global",
|
|
source: "owner/repo",
|
|
sourceType: "github",
|
|
skillsShUrl: "https://skills.sh/owner/repo/example-skill",
|
|
skillPath: "skills/example-skill/SKILL.md",
|
|
versionHash: "current-hash",
|
|
canCheckForUpdates: true,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function jsonResponse(value, status = 200) {
|
|
return new Response(JSON.stringify(value), {
|
|
status,
|
|
headers: { "Content-Type": "application/json" },
|
|
});
|
|
}
|
|
|
|
test("compares a global lock version with the remote Git tree", async () => {
|
|
const seen = [];
|
|
const upToDate = await checkSkillUpdate(install(), {
|
|
fetcher: async (url) => {
|
|
seen.push(url);
|
|
return jsonResponse({
|
|
sha: "root-hash",
|
|
tree: [{ type: "tree", path: "skills/example-skill", sha: "current-hash" }],
|
|
});
|
|
},
|
|
});
|
|
|
|
assert.equal(upToDate.state, "up-to-date");
|
|
assert.equal(upToDate.latestVersion, "current-hash");
|
|
assert.match(seen[0], /repos\/owner\/repo\/git\/trees\/HEAD/);
|
|
|
|
const available = await checkSkillUpdate(install(), {
|
|
fetcher: async () => jsonResponse({
|
|
sha: "root-hash",
|
|
tree: [{ type: "tree", path: "skills/example-skill", sha: "next-hash" }],
|
|
}),
|
|
});
|
|
assert.equal(available.state, "update-available");
|
|
assert.equal(available.currentVersion, "current-hash");
|
|
assert.equal(available.latestVersion, "next-hash");
|
|
});
|
|
|
|
test("uses the repository hash for a root global skill", async () => {
|
|
const result = await checkSkillUpdate(install({ skillPath: "SKILL.md" }), {
|
|
fetcher: async () => jsonResponse({ sha: "next-root", tree: [] }),
|
|
});
|
|
|
|
assert.equal(result.state, "update-available");
|
|
assert.equal(result.latestVersion, "next-root");
|
|
});
|
|
|
|
test("compares a project lock version with the skills.sh snapshot", async () => {
|
|
let requestedUrl = "";
|
|
const result = await checkSkillUpdate(install({ scope: "project" }), {
|
|
skillsApiBase: "https://skills.test",
|
|
fetcher: async (url) => {
|
|
requestedUrl = url;
|
|
return jsonResponse({ hash: "current-hash" });
|
|
},
|
|
});
|
|
|
|
assert.equal(result.state, "up-to-date");
|
|
assert.equal(
|
|
requestedUrl,
|
|
"https://skills.test/api/download/owner/repo/example-skill",
|
|
);
|
|
});
|
|
|
|
test("returns unsupported without making a remote request", async () => {
|
|
let called = false;
|
|
const result = await checkSkillUpdate(
|
|
install({ canCheckForUpdates: false, versionHash: undefined }),
|
|
{ fetcher: async () => { called = true; return jsonResponse({}); } },
|
|
);
|
|
|
|
assert.equal(result.state, "unsupported");
|
|
assert.equal(called, false);
|
|
});
|
|
|
|
test("returns a scoped error when the remote check fails", async () => {
|
|
const result = await checkSkillUpdate(install(), {
|
|
fetcher: async () => jsonResponse({}, 503),
|
|
});
|
|
|
|
assert.equal(result.state, "error");
|
|
assert.equal(result.message, "HTTP 503");
|
|
assert.equal(skillUpdateKey(install()), "global\0owner/repo@example-skill");
|
|
});
|
|
|
|
test("falls back to Git when the GitHub API is rate limited", async () => {
|
|
let resolved = false;
|
|
const result = await checkSkillUpdate(install(), {
|
|
fetcher: async () => jsonResponse({}, 403),
|
|
resolveGitTreeHash: async () => {
|
|
resolved = true;
|
|
return "next-hash";
|
|
},
|
|
});
|
|
|
|
assert.equal(resolved, true);
|
|
assert.equal(result.state, "update-available");
|
|
assert.equal(result.latestVersion, "next-hash");
|
|
});
|
|
|
|
test("builds Pi-only update commands for each scope", () => {
|
|
assert.deepEqual(buildSkillUpdateArgs(install()), [
|
|
"skills",
|
|
"add",
|
|
"owner/repo/skills/example-skill",
|
|
"--skill",
|
|
"example-skill",
|
|
"-y",
|
|
"--agent",
|
|
"pi",
|
|
"-g",
|
|
]);
|
|
assert.deepEqual(buildSkillUpdateArgs(install({ scope: "project" })), [
|
|
"skills",
|
|
"add",
|
|
"owner/repo/skills/example-skill",
|
|
"--skill",
|
|
"example-skill",
|
|
"-y",
|
|
"--agent",
|
|
"pi",
|
|
]);
|
|
assert.deepEqual(buildSkillUpdateArgs(install({ ref: "release/v2" })), [
|
|
"skills",
|
|
"add",
|
|
"owner/repo/skills/example-skill#release%2Fv2",
|
|
"--skill",
|
|
"example-skill",
|
|
"-y",
|
|
"--agent",
|
|
"pi",
|
|
"-g",
|
|
]);
|
|
});
|
|
|
|
test("reuses one remote request for skills from the same GitHub source", async () => {
|
|
let requests = 0;
|
|
const results = await checkSkillUpdates([
|
|
install(),
|
|
install({
|
|
package: "owner/repo@another-skill",
|
|
skillPath: "skills/another-skill/SKILL.md",
|
|
versionHash: "another-hash",
|
|
}),
|
|
], {
|
|
fetcher: async () => {
|
|
requests++;
|
|
return jsonResponse({
|
|
sha: "root-hash",
|
|
tree: [
|
|
{ type: "tree", path: "skills/example-skill", sha: "current-hash" },
|
|
{ type: "tree", path: "skills/another-skill", sha: "another-hash" },
|
|
],
|
|
});
|
|
},
|
|
});
|
|
|
|
assert.equal(requests, 1);
|
|
assert.deepEqual(results.map((item) => item.state), ["up-to-date", "up-to-date"]);
|
|
});
|