Files
vibn-frontend/vibn-agent-runner/dist/tools/skills-api.js

41 lines
1.8 KiB
JavaScript

"use strict";
// =============================================================================
// Pure skills API. Skills live in a Gitea repo at .skills/<name>/SKILL.md.
// Takes a GiteaReadConfig so it can read from any Gitea instance (in-process
// agent passes ctx.gitea, MCP server loads from env).
// =============================================================================
Object.defineProperty(exports, "__esModule", { value: true });
exports.listSkills = listSkills;
exports.getSkill = getSkill;
const SKILL_FILE = 'SKILL.md';
const SKILLS_DIR = '.skills';
async function giteaGetContents(cfg, repo, filePath) {
const res = await fetch(`${cfg.apiUrl}/api/v1/repos/${repo}/contents/${filePath}`, {
headers: { Authorization: `token ${cfg.apiToken}` },
});
if (!res.ok)
return null;
return res.json();
}
async function listSkills(cfg, repo) {
const contents = await giteaGetContents(cfg, repo, SKILLS_DIR);
if (!contents || !Array.isArray(contents)) {
return { skills: [], message: `No .skills/ directory found in ${repo}` };
}
const skills = contents
.filter((entry) => entry.type === 'dir')
.map((entry) => ({ name: entry.name, path: entry.path }));
return { repo, skills };
}
async function getSkill(cfg, repo, skillName) {
const filePath = `${SKILLS_DIR}/${skillName}/${SKILL_FILE}`;
const file = await giteaGetContents(cfg, repo, filePath);
if (!file || !file.content) {
return { error: `Skill "${skillName}" not found in ${repo}. Try list_skills to see available skills.` };
}
const content = Buffer.from(file.content, 'base64').toString('utf8');
// Strip YAML frontmatter if present, return just the markdown body
const body = content.replace(/^---[\s\S]*?---\s*/m, '').trim();
return { repo, skill: skillName, content: body };
}