mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-17 19:20:39 +09:00
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:
parent
bb46423969
commit
5890b318c4
39 changed files with 9902 additions and 309 deletions
|
|
@ -49,10 +49,10 @@ async function buildSkillsDir(config: Record<string, unknown>): Promise<string>
|
|||
),
|
||||
);
|
||||
for (const entry of availableEntries) {
|
||||
if (!desiredNames.has(entry.name)) continue;
|
||||
if (!desiredNames.has(entry.key)) continue;
|
||||
await fs.symlink(
|
||||
entry.source,
|
||||
path.join(target, entry.name),
|
||||
path.join(target, entry.runtimeName),
|
||||
);
|
||||
}
|
||||
return tmp;
|
||||
|
|
|
|||
|
|
@ -14,17 +14,18 @@ const __moduleDir = path.dirname(fileURLToPath(import.meta.url));
|
|||
|
||||
async function buildClaudeSkillSnapshot(config: Record<string, unknown>): Promise<AdapterSkillSnapshot> {
|
||||
const availableEntries = await readPaperclipRuntimeSkillEntries(config, __moduleDir);
|
||||
const availableByName = new Map(availableEntries.map((entry) => [entry.name, entry]));
|
||||
const availableByKey = new Map(availableEntries.map((entry) => [entry.key, entry]));
|
||||
const desiredSkills = resolvePaperclipDesiredSkillNames(config, availableEntries);
|
||||
const desiredSet = new Set(desiredSkills);
|
||||
const entries: AdapterSkillEntry[] = availableEntries.map((entry) => ({
|
||||
name: entry.name,
|
||||
desired: desiredSet.has(entry.name),
|
||||
key: entry.key,
|
||||
runtimeName: entry.runtimeName,
|
||||
desired: desiredSet.has(entry.key),
|
||||
managed: true,
|
||||
state: desiredSet.has(entry.name) ? "configured" : "available",
|
||||
state: desiredSet.has(entry.key) ? "configured" : "available",
|
||||
sourcePath: entry.source,
|
||||
targetPath: null,
|
||||
detail: desiredSet.has(entry.name)
|
||||
detail: desiredSet.has(entry.key)
|
||||
? "Will be mounted into the ephemeral Claude skill directory on the next run."
|
||||
: null,
|
||||
required: Boolean(entry.required),
|
||||
|
|
@ -33,10 +34,11 @@ async function buildClaudeSkillSnapshot(config: Record<string, unknown>): Promis
|
|||
const warnings: string[] = [];
|
||||
|
||||
for (const desiredSkill of desiredSkills) {
|
||||
if (availableByName.has(desiredSkill)) continue;
|
||||
if (availableByKey.has(desiredSkill)) continue;
|
||||
warnings.push(`Desired skill "${desiredSkill}" is not available from the Paperclip skills directory.`);
|
||||
entries.push({
|
||||
name: desiredSkill,
|
||||
key: desiredSkill,
|
||||
runtimeName: null,
|
||||
desired: true,
|
||||
managed: true,
|
||||
state: "missing",
|
||||
|
|
@ -46,7 +48,7 @@ async function buildClaudeSkillSnapshot(config: Record<string, unknown>): Promis
|
|||
});
|
||||
}
|
||||
|
||||
entries.sort((left, right) => left.name.localeCompare(right.name));
|
||||
entries.sort((left, right) => left.key.localeCompare(right.key));
|
||||
|
||||
return {
|
||||
adapterType: "claude_local",
|
||||
|
|
@ -71,7 +73,7 @@ export async function syncClaudeSkills(
|
|||
|
||||
export function resolveClaudeDesiredSkillNames(
|
||||
config: Record<string, unknown>,
|
||||
availableEntries: Array<{ name: string; required?: boolean }>,
|
||||
availableEntries: Array<{ key: string; required?: boolean }>,
|
||||
) {
|
||||
return resolvePaperclipDesiredSkillNames(config, availableEntries);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue