Skip to content

Commit 211d7aa

Browse files
24baigeiclaude
andcommitted
feat(skills-hub): add category browsing and bulk selection
Add ClawHub-style category navigation to the Skills Hub. Since the public ClawHub API returns no category data, classify skills locally by keyword against topics/name/summary into the 14 upstream categories. - Store and Installed tabs gain a category chip row with live counts; each card shows its primary-category icon and clickable category badges. - Preserve and surface the previously-dropped `topics` field on cards. - Store tab auto-fetches more pages when a category filter yields a sparse page, so local filtering over cursor pagination stays populated. - Add a bulk-select mode (Installed + Import tabs only) with click-to-toggle and Shift+click range selection, an undo toast, and protection for the always-on skills-creator/skills-installer skills. Icons reuse the project's ~icons/lucide pipeline; copy is fully i18n'd. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent c7cc354 commit 211d7aa

6 files changed

Lines changed: 975 additions & 13 deletions

File tree

crates/agent-gui/src/components/icons.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import McpLogoSource from "~icons/gravity-ui/logo-mcp";
33
import ConnectionIconSource from "~icons/gravity-ui/plug-connection";
44
import ClaudeSource from "~icons/logos/claude-icon";
55
import OpenAISource from "~icons/logos/openai-icon";
6+
import ActivitySource from "~icons/lucide/activity";
67
import ArchiveSource from "~icons/lucide/archive";
78
import ArchiveRestoreSource from "~icons/lucide/archive-restore";
89
import ArrowLeftSource from "~icons/lucide/arrow-left";
@@ -48,10 +49,12 @@ import GlobeSource from "~icons/lucide/globe";
4849
import GlobeOffSource from "~icons/lucide/globe-off";
4950
import GripVerticalSource from "~icons/lucide/grip-vertical";
5051
import HistorySource from "~icons/lucide/history";
52+
import HouseSource from "~icons/lucide/house";
5153
import ImageIconSource from "~icons/lucide/image";
5254
import ImageOffSource from "~icons/lucide/image-off";
5355
import InfoSource from "~icons/lucide/info";
5456
import KeySource from "~icons/lucide/key";
57+
import LayersSource from "~icons/lucide/layers";
5558
import LayoutGridSource from "~icons/lucide/layout-grid";
5659
import LightbulbSource from "~icons/lucide/lightbulb";
5760
import LightbulbOffSource from "~icons/lucide/lightbulb-off";
@@ -63,12 +66,15 @@ import LoaderCircleSource from "~icons/lucide/loader-circle";
6366
import LockSource from "~icons/lucide/lock";
6467
import LogOutSource from "~icons/lucide/log-out";
6568
import Maximize2Source from "~icons/lucide/maximize-2";
69+
import MessageCircleSource from "~icons/lucide/message-circle";
6670
import MessageSquareSource from "~icons/lucide/message-square";
6771
import MessageSquareTextSource from "~icons/lucide/message-square-text";
6872
import Minimize2Source from "~icons/lucide/minimize-2";
6973
import MinusSource from "~icons/lucide/minus";
7074
import MonitorSmartphoneSource from "~icons/lucide/monitor-smartphone";
7175
import MoonSource from "~icons/lucide/moon";
76+
import PackageSource from "~icons/lucide/package";
77+
import PaletteSource from "~icons/lucide/palette";
7278
import PanelLeftSource from "~icons/lucide/panel-left";
7379
import PanelLeftCloseSource from "~icons/lucide/panel-left-close";
7480
import PanelRightCloseSource from "~icons/lucide/panel-right-close";
@@ -109,6 +115,7 @@ import Trash2Source from "~icons/lucide/trash-2";
109115
import AlertTriangleSource from "~icons/lucide/triangle-alert";
110116
import Undo2Source from "~icons/lucide/undo-2";
111117
import UploadSource from "~icons/lucide/upload";
118+
import WalletSource from "~icons/lucide/wallet";
112119
import WaypointsSource from "~icons/lucide/waypoints";
113120
import WifiSource from "~icons/lucide/wifi";
114121
import WifiOffSource from "~icons/lucide/wifi-off";
@@ -448,6 +455,7 @@ export const GeminiIcon = createIcon(GeminiIconSource);
448455
export const Archive = createIcon(ArchiveSource);
449456
export const ArchiveRestore = createIcon(ArchiveRestoreSource);
450457
export const ArrowLeft = createIcon(ArrowLeftSource);
458+
export const Activity = createIcon(ActivitySource);
451459
export const Ban = createIcon(BanSource);
452460
export const Blend = createIcon(BlendSource);
453461
export const BookOpen = createIcon(BookOpenSource);
@@ -489,10 +497,12 @@ export const GitCommitHorizontal = createIcon(GitCommitHorizontalSource);
489497
export const Github = createIcon(GithubSource);
490498
export const GripVertical = createIcon(GripVerticalSource);
491499
export const History = createIcon(HistorySource);
500+
export const House = createIcon(HouseSource);
492501
export const ImageIcon = createIcon(ImageIconSource);
493502
export const ImageOff = createIcon(ImageOffSource);
494503
export const Info = createIcon(InfoSource);
495504
export const Key = createIcon(KeySource);
505+
export const Layers = createIcon(LayersSource);
496506
export const LayoutGrid = createIcon(LayoutGridSource);
497507
export const Link2 = createIcon(Link2Source);
498508
export const Lightbulb = createIcon(LightbulbSource);
@@ -504,6 +514,7 @@ export const LoaderCircle = createIcon(LoaderCircleSource);
504514
export const Lock = createIcon(LockSource);
505515
export const LogOut = createIcon(LogOutSource);
506516
export const Maximize2 = createIcon(Maximize2Source);
517+
export const MessageCircle = createIcon(MessageCircleSource);
507518
export const MessageSquare = createIcon(MessageSquareSource);
508519
export const MessageSquareText = createIcon(MessageSquareTextSource);
509520
export const McpLogo = createIcon(McpLogoSource);
@@ -519,6 +530,8 @@ export const PanelRightClose = createIcon(PanelRightCloseSource);
519530
export const PanelRightOpen = createIcon(PanelRightOpenSource);
520531
export const Paperclip = createIcon(PaperclipSource);
521532
export const Pencil = createIcon(PencilSource);
533+
export const Package = createIcon(PackageSource);
534+
export const Palette = createIcon(PaletteSource);
522535
export const Pin = createIcon(PinSource);
523536
export const PinOff = createIcon(PinOffSource);
524537
export const Play = createIcon(PlaySource);
@@ -553,6 +566,7 @@ export const TextSelect = createIcon(TextSelectSource);
553566
export const Trash2 = createIcon(Trash2Source);
554567
export const Undo2 = createIcon(Undo2Source);
555568
export const Upload = createIcon(UploadSource);
569+
export const Wallet = createIcon(WalletSource);
556570
export const Waypoints = createIcon(WaypointsSource);
557571
export const Wifi = createIcon(WifiSource);
558572
export const WifiOff = createIcon(WifiOffSource);

crates/agent-gui/src/i18n/config.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,6 +1721,26 @@ export const translations: Record<Locale, Record<string, string>> = {
17211721
"settings.skillsSearch": "搜索技能...",
17221722
"settings.skillsNoMatch": "没有匹配「{filter}」的技能",
17231723
"settings.skillsStoreSearch": "搜索 ClawHub 技能",
1724+
"settings.skillsBulkSelect": "批量选择",
1725+
"settings.skillsBulkHint": "点击卡片切换开关 · Shift+点击可批量选择一段区间",
1726+
"settings.skillsBulkImportHint": "点击卡片勾选 · Shift+点击可批量选择一段区间",
1727+
"settings.skillsBulkUpdated": "已更新 {count} 个技能",
1728+
"settings.skillsBulkUndo": "撤销",
1729+
"settings.skillsStoreCategoryAll": "全部",
1730+
"settings.skillsStoreCategoryIntegrations": "集成",
1731+
"settings.skillsStoreCategoryAutomation": "自动化",
1732+
"settings.skillsStoreCategoryResearch": "研究",
1733+
"settings.skillsStoreCategoryDevelopment": "开发",
1734+
"settings.skillsStoreCategoryProductivity": "效率",
1735+
"settings.skillsStoreCategoryCommunication": "沟通",
1736+
"settings.skillsStoreCategoryCreative": "创意",
1737+
"settings.skillsStoreCategoryKnowledge": "知识",
1738+
"settings.skillsStoreCategoryAgents": "智能体",
1739+
"settings.skillsStoreCategoryOperations": "运维",
1740+
"settings.skillsStoreCategorySecurity": "安全",
1741+
"settings.skillsStoreCategoryFinance": "金融",
1742+
"settings.skillsStoreCategoryLifestyle": "生活",
1743+
"settings.skillsStoreCategoryOther": "其他",
17241744
"settings.skillsStoreSortMostDownloaded": "下载最多",
17251745
"settings.skillsStoreSortMostStarred": "星标最多",
17261746
"settings.skillsStoreSortMostInstalled": "安装最多",
@@ -3620,6 +3640,26 @@ export const translations: Record<Locale, Record<string, string>> = {
36203640
"settings.skillsSearch": "Search Skills...",
36213641
"settings.skillsNoMatch": 'No skills matching "{filter}"',
36223642
"settings.skillsStoreSearch": "Search ClawHub Skills",
3643+
"settings.skillsBulkSelect": "Bulk Select",
3644+
"settings.skillsBulkHint": "Click a card to toggle · Shift+click to select a range",
3645+
"settings.skillsBulkImportHint": "Click a card to check · Shift+click to select a range",
3646+
"settings.skillsBulkUpdated": "Updated {count} skills",
3647+
"settings.skillsBulkUndo": "Undo",
3648+
"settings.skillsStoreCategoryAll": "All",
3649+
"settings.skillsStoreCategoryIntegrations": "Integrations",
3650+
"settings.skillsStoreCategoryAutomation": "Automation",
3651+
"settings.skillsStoreCategoryResearch": "Research",
3652+
"settings.skillsStoreCategoryDevelopment": "Development",
3653+
"settings.skillsStoreCategoryProductivity": "Productivity",
3654+
"settings.skillsStoreCategoryCommunication": "Communication",
3655+
"settings.skillsStoreCategoryCreative": "Creative",
3656+
"settings.skillsStoreCategoryKnowledge": "Knowledge",
3657+
"settings.skillsStoreCategoryAgents": "Agents",
3658+
"settings.skillsStoreCategoryOperations": "Operations",
3659+
"settings.skillsStoreCategorySecurity": "Security",
3660+
"settings.skillsStoreCategoryFinance": "Finance",
3661+
"settings.skillsStoreCategoryLifestyle": "Lifestyle",
3662+
"settings.skillsStoreCategoryOther": "Other",
36233663
"settings.skillsStoreSortMostDownloaded": "Most Downloaded",
36243664
"settings.skillsStoreSortMostStarred": "Most Starred",
36253665
"settings.skillsStoreSortMostInstalled": "Most Installed",

crates/agent-gui/src/lib/skills/clawHub.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ export type ClawHubSkillCard = {
44
slug: string;
55
displayName: string;
66
summary: string;
7+
/** ClawHub 上的自由标签,用于本地分类与卡片标签展示。 */
8+
topics: string[];
79
latestVersion: string | null;
810
downloads: number;
911
stars: number;
@@ -78,6 +80,7 @@ export function normalizeClawHubSkillCard(raw: unknown): ClawHubSkillCard | null
7880
slug,
7981
displayName: asString(item.displayName) ?? slug,
8082
summary: asString(item.summary) ?? "",
83+
topics: asStringArray(item.topics),
8184
latestVersion:
8285
asString(latestVersion.version) ?? asString(tags.latest) ?? asString(item.version),
8386
downloads: asNullableNumber(item.downloads) ?? asNullableNumber(stats.downloads) ?? 0,

0 commit comments

Comments
 (0)