hooks-transforms/skill-install.ts

66 lines
2.3 KiB
TypeScript
Raw Normal View History

/**
* Transform for skill-update webhook.
*
* Expected payload (skill.allowlist.updated event):
* skills[].repo_url (required) git clone URL
* skills[].skill_slug (required) used as directory name under ~/clawd/skills/
* skills[].git_ref (optional) branch/tag to checkout
* skills[].repo_subpath (optional) subdirectory within the repo containing the skill
*/
interface SkillEntry {
skill_id?: string;
skill_slug?: string;
skill_name?: string;
repo_url?: string;
repo_subpath?: string;
git_ref?: string;
commit_sha?: string;
2026-03-14 02:35:01 +00:00
}
export function transformSkillInstall(payload: Record<string, unknown>) {
const body = (payload.payload ?? payload) as Record<string, unknown>;
const skills = body.skills as SkillEntry[] | undefined;
2026-03-14 02:35:01 +00:00
if (!skills || skills.length === 0) {
return {
message: "skill-update webhook received but no `skills` array in payload. Nothing to install.",
};
}
const lines: string[] = [
`Install/update ${skills.length} skill(s) from git. Execute all steps directly — do not ask questions.`,
``,
];
for (const skill of skills) {
const { repo_url, skill_slug, skill_name, git_ref, repo_subpath } = skill;
if (!repo_url) {
lines.push(`⚠️ Skipping skill "${skill_slug ?? "unknown"}" — missing repo_url.`, ``);
continue;
2026-03-14 02:35:01 +00:00
}
const dirName = skill_slug ?? repo_url.split("/").pop()?.replace(/\.git$/, "") ?? "unknown-skill";
const installPath = `~/clawd/skills/${dirName}`;
const skillDir = repo_subpath ? `${installPath}/${repo_subpath}` : installPath;
lines.push(
`── Skill: ${skill_name ?? dirName} (${git_ref ?? "default branch"})`,
` Repo: ${repo_url}`,
` Target: ${skillDir}`,
``,
` Steps:`,
` 1. If ${installPath} exists: cd ${installPath} && git fetch --tags && git checkout ${git_ref ?? "HEAD"}`,
` Otherwise: git clone ${repo_url} ${installPath} && cd ${installPath} && git checkout ${git_ref ?? "HEAD"}`,
` 2. cd ${skillDir}`,
` 3. If install.sh exists: bash install.sh`,
` Otherwise: npm install (if package.json exists) or skip`,
` 4. Reply with one line: installed/updated + skill name + version.`,
``,
);
2026-03-14 02:35:01 +00:00
}
return { message: lines.join("\n") };
2026-03-14 02:35:01 +00:00
}