Namespace company skill identities

Persist canonical namespaced skill keys, split adapter runtime names from skill keys, and update portability/import flows to carry the canonical identity end-to-end.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Dotta 2026-03-16 18:27:20 -05:00
parent bb46423969
commit 5890b318c4
39 changed files with 9902 additions and 309 deletions

View file

@ -31,6 +31,7 @@ async function createCustomSkill(root: string, skillName: string) {
}
describe("codex local adapter skill injection", () => {
const paperclipKey = "paperclipai/paperclip/paperclip";
const cleanupDirs = new Set<string>();
afterEach(async () => {
@ -57,14 +58,18 @@ describe("codex local adapter skill injection", () => {
},
{
skillsHome,
skillsEntries: [{ name: "paperclip", source: path.join(currentRepo, "skills", "paperclip") }],
skillsEntries: [{
key: paperclipKey,
runtimeName: "paperclip",
source: path.join(currentRepo, "skills", "paperclip"),
}],
},
);
expect(await fs.realpath(path.join(skillsHome, "paperclip"))).toBe(
await fs.realpath(path.join(currentRepo, "skills", "paperclip")),
);
expect(logs.some((line) => line.includes('Repaired Codex skill "paperclip"'))).toBe(true);
expect(logs.some((line) => line.includes("Repaired Codex skill"))).toBe(true);
});
it("preserves a custom Codex skill symlink outside Paperclip repo checkouts", async () => {
@ -81,7 +86,11 @@ describe("codex local adapter skill injection", () => {
await ensureCodexSkillsInjected(async () => {}, {
skillsHome,
skillsEntries: [{ name: "paperclip", source: path.join(currentRepo, "skills", "paperclip") }],
skillsEntries: [{
key: paperclipKey,
runtimeName: "paperclip",
source: path.join(currentRepo, "skills", "paperclip"),
}],
});
expect(await fs.realpath(path.join(skillsHome, "paperclip"))).toBe(