diff --git a/ui/src/pages/CompanySkills.tsx b/ui/src/pages/CompanySkills.tsx index 1fb8cba530d..35b0c8568b2 100644 --- a/ui/src/pages/CompanySkills.tsx +++ b/ui/src/pages/CompanySkills.tsx @@ -6,7 +6,6 @@ import type { Agent, CatalogSkill, CatalogSkillFileDetail, - CompanySkillComment, CompanySkillCompatibility, CompanySkillCreateRequest, CompanySkillDetail, @@ -32,6 +31,7 @@ import { MarkdownEditor } from "../components/MarkdownEditor"; import { PageSkeleton } from "../components/PageSkeleton"; import { CopyText } from "../components/CopyText"; import { Identity } from "../components/Identity"; +import { AgentIcon } from "../components/AgentIconPicker"; import { useAdapterCapabilities } from "../adapters/use-adapter-capabilities"; import { Dialog, @@ -86,9 +86,9 @@ import { LayoutGrid, Link2, Lock, - MessageSquare, ExternalLink, Paperclip, + Pause, Pencil, Plus, Copy, @@ -537,7 +537,9 @@ function cardDescriptionText(raw: string | null | undefined): string { const cleaned = (raw ?? "") .replace(/^[\s>#*_\-`>]+/, "") .trim(); - return cleaned.length >= 3 ? cleaned : "No description yet."; + // Empty descriptions render as a blank line on cards so spacing stays + // consistent across the grid (PAP-10907). + return cleaned.length >= 3 ? cleaned : ""; } // --------------------------------------------------------------------------- @@ -823,7 +825,7 @@ function SkillCard({ card, onOpen }: { card: DiscoveryCard; onOpen: (card: Disco type="button" onClick={() => onOpen(card)} className={cn( - "group flex h-full min-h-[11.5rem] flex-col rounded-md border border-border p-4 text-left transition-colors hover:border-foreground/30 hover:bg-accent/30 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", + "group flex h-full min-h-[11.5rem] flex-col rounded-md border border-border p-4 text-left transition-colors hover:border-primary hover:bg-accent/30 hover:shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", card.required && "bg-muted/30", )} > @@ -844,38 +846,41 @@ function SkillCard({ card, onOpen }: { card: DiscoveryCard; onOpen: (card: Disco ) : null} -

+ {/* Always reserve two lines so cards line up even without a description. */} +

{cardDescriptionText(card.description)}

+ {/* Stats: installed agents · stars · forks — stars/forks only when > 0. */}
- {card.required ? ( - {card.agentCount} agents using - ) : ( + {card.agentCount} {card.agentCount === 1 ? "agent" : "agents"} + {card.starCount > 0 ? ( <> + - - {card.agentCount} agents - - - )} + ) : null} + {card.forkCount > 0 ? ( + <> + + + + ) : null}
+ {card.installed ? ( + + Installed + + ) : null} {card.categories.slice(0, 2).map((category) => ( ))} - {card.required ? ( - + - ) : card.installed ? ( - - ) : null}
@@ -976,10 +981,13 @@ export function DiscoveryGrid({ scanStatus: string | null; }) { return ( -
+ // On desktop the store is bounded to the viewport so the category sidebar + // and the results pane each scroll independently (PAP-10907). Mobile keeps + // the natural page flow. +
{/* Secondary category sidebar — the main app nav collapses to a rail while this is present (handled in Layout). */} -