diff --git a/ui/src/pages/SkillBrowser.tsx b/ui/src/pages/SkillBrowser.tsx index e5f4bc82..f8cbaf31 100644 --- a/ui/src/pages/SkillBrowser.tsx +++ b/ui/src/pages/SkillBrowser.tsx @@ -38,6 +38,13 @@ import { PageTabBar } from "@/components/PageTabBar"; import { PageSkeleton } from "@/components/PageSkeleton"; import { Identity } from "@/components/Identity"; import { cn } from "@/lib/utils"; +import { getUIAdapter } from "@/adapters"; +import { resolveAdapterSkillConfig, listAdapterSkillConfigs } from "@paperclipai/adapter-utils"; + +// Compute compatible adapter labels once at module level (used by Browse/Trending SkillCards) +const COMPATIBLE_ADAPTER_LABELS = listAdapterSkillConfigs() + .filter((c) => c.supportsInstall) + .map((c) => getUIAdapter(c.adapterType).label); type SortBy = "rating" | "name" | "recent"; @@ -62,6 +69,7 @@ export function SkillBrowser() { // Dialog state const [installDialog, setInstallDialog] = useState<{ skillId: string; isUpdate?: boolean } | null>(null); const [uninstallDialog, setUninstallDialog] = useState<{ skillId: string; agentId: string } | null>(null); + const [unsupportedMessage, setUnsupportedMessage] = useState(null); useEffect(() => { setBreadcrumbs([ @@ -253,6 +261,16 @@ export function SkillBrowser() { const handleInstallForAgent = (agentId: string) => { if (!installDialog) return; + const agent = agents.find((a) => a.id === agentId); + if (agent) { + const cfg = resolveAdapterSkillConfig(agent.adapterType ?? "process"); + if (!cfg.supportsInstall) { + setUnsupportedMessage( + cfg.unsupportedReason ?? "This adapter does not support skill installation." + ); + return; + } + } if (installDialog.isUpdate) { updateMutation.mutate({ skillId: installDialog.skillId, agentId }); } else { @@ -413,6 +431,9 @@ export function SkillBrowser() { onClick={() => setSelectedAgentId(agent.id)} > + + ({getUIAdapter(agent.adapterType ?? "process").label}) + ))} @@ -432,6 +453,14 @@ export function SkillBrowser() { {agents.find((a) => a.id === selectedAgentId)?.name ?? selectedAgentId} + {(() => { + const a = agents.find((ag) => ag.id === selectedAgentId); + return a ? ( + + ({getUIAdapter(a.adapterType ?? "process").label}) + + ) : null; + })()} @@ -573,7 +602,10 @@ export function SkillBrowser() { { - if (!open) setInstallDialog(null); + if (!open) { + setInstallDialog(null); + setUnsupportedMessage(null); + } }} > @@ -584,6 +616,15 @@ export function SkillBrowser() {
+ {unsupportedMessage && ( +
+

Cannot install on this agent

+

{unsupportedMessage}

+ +
+ )}
{agents.length === 0 && (

No agents found in this workspace.

@@ -597,6 +638,9 @@ export function SkillBrowser() { onClick={() => handleInstallForAgent(agent.id)} > + + ({getUIAdapter(agent.adapterType ?? "process").label}) + ))}
@@ -604,7 +648,10 @@ export function SkillBrowser() {