feat: Integrate ClawdHub skill registry

This commit is contained in:
Bohdan Triapitsyn
2026-01-10 01:01:47 +02:00
parent 591cbb723a
commit 21fdba08a3
16 changed files with 1651 additions and 23 deletions
@@ -55,12 +55,23 @@ export const InstallSkillDialog: React.FC<InstallSkillDialogProps> = ({ open, on
skillDir: string;
conflictDecisions?: Record<string, ConflictDecision>;
}) => {
// Build selection with clawdhub metadata if present
const selection: { skillDir: string; clawdhub?: { slug: string; version: string } } = {
skillDir: request.skillDir,
};
if (item?.clawdhub) {
selection.clawdhub = {
slug: item.clawdhub.slug,
version: item.clawdhub.version,
};
}
const result = await installSkills({
source: request.source,
subpath: request.subpath,
gitIdentityId: item?.gitIdentityId,
scope: request.scope,
selections: [{ skillDir: request.skillDir }],
selections: [selection],
conflictPolicy: 'prompt',
conflictDecisions: request.conflictDecisions,
});
@@ -11,7 +11,7 @@ import {
SelectTrigger,
} from '@/components/ui/select';
import { RiAddLine, RiDeleteBinLine, RiRefreshLine } from '@remixicon/react';
import { RiAddLine, RiDeleteBinLine, RiRefreshLine, RiDownloadLine, RiStarLine } from '@remixicon/react';
import { useSkillsCatalogStore } from '@/stores/useSkillsCatalogStore';
import type { SkillsCatalogItem } from '@/lib/api/types';
@@ -254,6 +254,24 @@ export const SkillsCatalogPage: React.FC<SkillsCatalogPageProps> = ({ mode, onMo
) : (
<div className="typography-micro text-muted-foreground mt-0.5">No description provided</div>
)}
{item.clawdhub ? (
<div className="typography-micro text-muted-foreground mt-1 flex items-center gap-3">
{item.clawdhub.owner ? (
<span>by {item.clawdhub.owner}</span>
) : null}
<span className="flex items-center gap-1">
<RiDownloadLine className="h-3 w-3" />
{item.clawdhub.downloads?.toLocaleString() ?? 0}
</span>
{(item.clawdhub.stars ?? 0) > 0 ? (
<span className="flex items-center gap-1">
<RiStarLine className="h-3 w-3" />
{item.clawdhub.stars}
</span>
) : null}
<span>v{item.clawdhub.version}</span>
</div>
) : null}
{item.warnings?.length ? (
<div className="typography-micro text-muted-foreground mt-1">{item.warnings.join(' · ')}</div>
) : null}
+22
View File
@@ -456,12 +456,15 @@ export type RuntimeAPISelector<TValue> = (apis: RuntimeAPIs) => TValue;
export type SkillsCatalogSourceId = string;
export type SkillsCatalogSourceType = 'github' | 'clawdhub';
export interface SkillsCatalogSource {
id: SkillsCatalogSourceId;
label: string;
description?: string;
source: string;
defaultSubpath?: string;
sourceType?: SkillsCatalogSourceType;
}
export interface SkillsCatalogItemInstalledBadge {
@@ -469,6 +472,18 @@ export interface SkillsCatalogItemInstalledBadge {
scope?: 'user' | 'project';
}
export interface ClawdHubSkillMetadata {
slug: string;
version: string;
displayName?: string;
owner?: string;
downloads?: number;
stars?: number;
versionsCount?: number;
createdAt?: number;
updatedAt?: number;
}
export interface SkillsCatalogItem {
sourceId: SkillsCatalogSourceId;
repoSource: string;
@@ -481,6 +496,8 @@ export interface SkillsCatalogItem {
installable: boolean;
warnings?: string[];
installed?: SkillsCatalogItemInstalledBadge;
/** ClawdHub-specific metadata (present only for ClawdHub sources) */
clawdhub?: ClawdHubSkillMetadata;
}
export interface SkillsCatalogResponse {
@@ -511,6 +528,11 @@ export interface SkillsRepoScanResponse {
export interface SkillsInstallSelection {
skillDir: string;
/** ClawdHub-specific metadata for installation */
clawdhub?: {
slug: string;
version: string;
};
}
export interface SkillsInstallRequest {