'use strict'; var chunk64ITUOXI_cjs = require('./chunk-64ITUOXI.cjs'); // src/server/handlers/skills-sh-shared.ts var SKILLS_SH_API_URL = "https://skills-api-production.up.railway.app"; var SKILLS_SH_DIR = ".agents/skills"; var SEARCH_TIMEOUT_MS = 1e4; var PREVIEW_TIMEOUT_MS = 1e4; var FILE_FETCH_TIMEOUT_MS = 3e4; var SKILL_NAME_REGEX = /^[a-z0-9][a-z0-9-_]*$/i; function assertSafeSkillName(name) { if (!SKILL_NAME_REGEX.test(name)) { throw new chunk64ITUOXI_cjs.HTTPException(400, { message: `Invalid skill name "${name}". Names must start with alphanumeric and contain only letters, numbers, hyphens, and underscores.` }); } return name; } function assertSafeFilePath(filePath) { if (filePath.startsWith("/") || filePath.startsWith("\\") || /^[a-zA-Z]:[\\/]/.test(filePath)) { throw new chunk64ITUOXI_cjs.HTTPException(400, { message: `Invalid file path "${filePath}". Absolute paths are not allowed.` }); } const segments = filePath.split(/[\\/]/); for (const segment of segments) { if (segment === ".." || segment === ".") { throw new chunk64ITUOXI_cjs.HTTPException(400, { message: `Invalid file path "${filePath}". Path traversal is not allowed.` }); } } return filePath; } async function searchSkillsSh({ q, limit }) { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), SEARCH_TIMEOUT_MS); try { const url = `${SKILLS_SH_API_URL}/api/skills?query=${encodeURIComponent(q)}&pageSize=${limit}`; const response = await fetch(url, { signal: controller.signal }); if (!response.ok) { throw new chunk64ITUOXI_cjs.HTTPException(502, { message: `Skills API error: ${response.status} ${response.statusText}` }); } const data = await response.json(); return { query: q, searchType: "query", skills: data.skills.map((s) => ({ id: s.skillId, name: s.name, installs: s.installs, topSource: s.source })), count: data.total }; } finally { clearTimeout(timeoutId); } } async function getPopularSkillsSh({ limit, offset }) { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), SEARCH_TIMEOUT_MS); try { const page = offset > 0 ? Math.floor(offset / limit) + 1 : 1; const url = `${SKILLS_SH_API_URL}/api/skills/top?pageSize=${limit}&page=${page}`; const response = await fetch(url, { signal: controller.signal }); if (!response.ok) { throw new chunk64ITUOXI_cjs.HTTPException(502, { message: `Skills API error: ${response.status} ${response.statusText}` }); } const data = await response.json(); return { skills: data.skills.map((s) => ({ id: s.skillId, name: s.name, installs: s.installs, topSource: s.source })), count: data.total, limit, offset }; } finally { clearTimeout(timeoutId); } } async function previewSkillsSh({ owner, repo, skillName }) { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), PREVIEW_TIMEOUT_MS); try { const url = `${SKILLS_SH_API_URL}/api/skills/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/${encodeURIComponent(skillName)}/content`; const response = await fetch(url, { signal: controller.signal }); if (!response.ok) { if (response.status === 404) { throw new chunk64ITUOXI_cjs.HTTPException(404, { message: `Could not find skill "${skillName}" for ${owner}/${repo}` }); } throw new chunk64ITUOXI_cjs.HTTPException(502, { message: `Skills API error: ${response.status} ${response.statusText}` }); } const data = await response.json(); const content = data.instructions || data.raw || ""; if (!content) { throw new chunk64ITUOXI_cjs.HTTPException(404, { message: `No content available for skill "${skillName}"` }); } return { content }; } finally { clearTimeout(timeoutId); } } async function fetchSkillFiles(owner, repo, skillName) { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), FILE_FETCH_TIMEOUT_MS); try { const url = `${SKILLS_SH_API_URL}/api/skills/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/${encodeURIComponent(skillName)}/files`; const response = await fetch(url, { signal: controller.signal }); if (!response.ok) { if (response.status === 404) { return null; } throw new Error(`Skills API error: ${response.status} ${response.statusText}`); } return await response.json(); } finally { clearTimeout(timeoutId); } } exports.SKILLS_SH_API_URL = SKILLS_SH_API_URL; exports.SKILLS_SH_DIR = SKILLS_SH_DIR; exports.assertSafeFilePath = assertSafeFilePath; exports.assertSafeSkillName = assertSafeSkillName; exports.fetchSkillFiles = fetchSkillFiles; exports.getPopularSkillsSh = getPopularSkillsSh; exports.previewSkillsSh = previewSkillsSh; exports.searchSkillsSh = searchSkillsSh; //# sourceMappingURL=chunk-AR7VSXHH.cjs.map //# sourceMappingURL=chunk-AR7VSXHH.cjs.map