Files
openclaw-mission-control/frontend/src/lib/skills-source.ts

51 lines
1.5 KiB
TypeScript

export const normalizeRepoSourceUrl = (sourceUrl: string): string => {
const trimmed = sourceUrl.trim().replace(/\/+$/, "");
return trimmed.endsWith(".git") ? trimmed.slice(0, -4) : trimmed;
};
export const repoBaseFromSkillSourceUrl = (
skillSourceUrl: string,
): string | null => {
try {
const parsed = new URL(skillSourceUrl);
const marker = "/tree/";
const markerIndex = parsed.pathname.indexOf(marker);
if (markerIndex <= 0) return null;
// Reject unexpected structures (e.g. multiple /tree/ markers).
if (parsed.pathname.indexOf(marker, markerIndex + marker.length) !== -1)
return null;
const repoPath = parsed.pathname.slice(0, markerIndex);
if (!repoPath || repoPath === "/") return null;
if (repoPath.endsWith("/tree")) return null;
return normalizeRepoSourceUrl(`${parsed.origin}${repoPath}`);
} catch {
return null;
}
};
export const packUrlFromSkillSourceUrl = (skillSourceUrl: string): string => {
const repoBase = repoBaseFromSkillSourceUrl(skillSourceUrl);
return repoBase ?? skillSourceUrl;
};
export const packLabelFromUrl = (packUrl: string): string => {
try {
const parsed = new URL(packUrl);
const segments = parsed.pathname.split("/").filter(Boolean);
if (segments.length >= 2) {
return `${segments[0]}/${segments[1]}`;
}
return parsed.host;
} catch {
return "Open pack";
}
};
export const packsHrefFromPackUrl = (packUrl: string): string => {
const params = new URLSearchParams({ source_url: packUrl });
return `/skills/packs?${params.toString()}`;
};