From bb87b785f483042802cc3248ea4c4e0e51eac9a7 Mon Sep 17 00:00:00 2001 From: AlphaCat Date: Mon, 20 Jul 2026 22:43:31 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix(skills-hub):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=8D=A1=E7=89=87=E6=82=AC=E5=81=9C=E6=B8=B2=E6=9F=93=E4=BC=AA?= =?UTF-8?q?=E5=BD=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 移除已安装与商店技能卡片的 backdrop-blur-xl,避免 WebView2 在 hover transform 时产生过期背景采样条纹。 保留卡片背景、边框、阴影、位移与入场动画,并同步 GUI 与 Gateway Web。 --- .../web/src/pages/skills-hub/SkillsHubPage.tsx | 6 +++--- crates/agent-gui/src/pages/skills-hub/SkillsHubPage.tsx | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/agent-gateway/web/src/pages/skills-hub/SkillsHubPage.tsx b/crates/agent-gateway/web/src/pages/skills-hub/SkillsHubPage.tsx index 1f09cf2c4..afc84b86a 100644 --- a/crates/agent-gateway/web/src/pages/skills-hub/SkillsHubPage.tsx +++ b/crates/agent-gateway/web/src/pages/skills-hub/SkillsHubPage.tsx @@ -1924,7 +1924,7 @@ export function SkillsHubPage(props: SkillsHubPageProps) { openInstalledSkillPreview(skill); }} className={cn( - "hub-skill-card skill-card-enter group flex h-full w-full cursor-pointer flex-col rounded-2xl border border-border/50 bg-background/75 p-3.5 text-left backdrop-blur-xl shadow-[0_1px_0_rgba(255,255,255,0.55)_inset,0_4px_18px_-12px_rgba(15,23,42,0.16)] transition-all hover:-translate-y-0.5 hover:border-border/60 hover:bg-background/85 hover:shadow-[0_4px_16px_-10px_rgba(15,23,42,0.18)] dark:border-white/[0.08] dark:bg-white/[0.05] dark:shadow-[0_1px_0_rgba(255,255,255,0.05)_inset,0_4px_18px_-12px_rgba(0,0,0,0.5)] dark:hover:border-white/[0.12] dark:hover:bg-white/[0.07] dark:hover:shadow-[0_4px_16px_-10px_rgba(0,0,0,0.55)] focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-foreground/15", + "hub-skill-card skill-card-enter group flex h-full w-full cursor-pointer flex-col rounded-2xl border border-border/50 bg-background/75 p-3.5 text-left shadow-[0_1px_0_rgba(255,255,255,0.55)_inset,0_4px_18px_-12px_rgba(15,23,42,0.16)] transition-all hover:-translate-y-0.5 hover:border-border/60 hover:bg-background/85 hover:shadow-[0_4px_16px_-10px_rgba(15,23,42,0.18)] dark:border-white/[0.08] dark:bg-white/[0.05] dark:shadow-[0_1px_0_rgba(255,255,255,0.05)_inset,0_4px_18px_-12px_rgba(0,0,0,0.5)] dark:hover:border-white/[0.12] dark:hover:bg-white/[0.07] dark:hover:shadow-[0_4px_16px_-10px_rgba(0,0,0,0.55)] focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-foreground/15", bulkMode ? "cursor-default hover:translate-y-0" : null, )} > @@ -1971,7 +1971,7 @@ export function SkillsHubPage(props: SkillsHubPageProps) { }} className={cn( "hub-skill-card skill-card-enter group relative flex h-full w-full flex-col rounded-2xl border p-3.5 text-left transition-all", - "cursor-pointer backdrop-blur-xl focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-foreground/15", + "cursor-pointer focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-foreground/15", checked ? "border-emerald-500/35 bg-emerald-50/90 shadow-[0_1px_0_rgba(255,255,255,0.55)_inset,0_4px_14px_-12px_rgba(16,185,129,0.28)] dark:border-emerald-400/30 dark:bg-emerald-500/12 dark:shadow-[0_1px_0_rgba(255,255,255,0.05)_inset,0_4px_14px_-12px_rgba(16,185,129,0.22)]" : "border-border/40 bg-muted/45 text-muted-foreground shadow-none hover:-translate-y-0.5 hover:border-border/55 hover:bg-muted/55 dark:border-white/[0.06] dark:bg-white/[0.025] dark:hover:border-white/[0.10] dark:hover:bg-white/[0.04]", @@ -3174,7 +3174,7 @@ function SkillsStoreView(props: { } }} className={cn( - "skill-card-enter group flex h-full cursor-pointer flex-col rounded-2xl border p-3.5 text-left backdrop-blur-xl transition-all focus:outline-none focus:ring-2 focus:ring-foreground/10", + "skill-card-enter group flex h-full cursor-pointer flex-col rounded-2xl border p-3.5 text-left transition-all focus:outline-none focus:ring-2 focus:ring-foreground/10", done ? "border-border/55 bg-background/80 shadow-[0_1px_0_rgba(255,255,255,0.6)_inset,0_4px_18px_-12px_rgba(15,23,42,0.18)] dark:border-white/[0.10] dark:bg-white/[0.07] dark:shadow-[0_1px_0_rgba(255,255,255,0.07)_inset,0_4px_18px_-12px_rgba(0,0,0,0.55)]" : "border-border/40 bg-background/60 hover:-translate-y-0.5 hover:border-border/55 hover:bg-background/75 hover:shadow-[0_4px_16px_-10px_rgba(15,23,42,0.18)] dark:border-white/[0.05] dark:bg-white/[0.03] dark:hover:border-white/[0.10] dark:hover:bg-white/[0.06] dark:hover:shadow-[0_4px_16px_-10px_rgba(0,0,0,0.55)]", diff --git a/crates/agent-gui/src/pages/skills-hub/SkillsHubPage.tsx b/crates/agent-gui/src/pages/skills-hub/SkillsHubPage.tsx index 1df791ae3..1d76f8ede 100644 --- a/crates/agent-gui/src/pages/skills-hub/SkillsHubPage.tsx +++ b/crates/agent-gui/src/pages/skills-hub/SkillsHubPage.tsx @@ -2029,7 +2029,7 @@ export function SkillsHubPage(props: SkillsHubPageProps) { openInstalledSkillPreview(skill); }} className={cn( - "hub-skill-card skill-card-enter group flex h-full w-full cursor-pointer flex-col rounded-2xl border border-border/50 bg-background/75 p-3.5 text-left backdrop-blur-xl shadow-[0_1px_0_rgba(255,255,255,0.55)_inset,0_4px_18px_-12px_rgba(15,23,42,0.16)] transition-all hover:-translate-y-0.5 hover:border-border/60 hover:bg-background/85 hover:shadow-[0_4px_16px_-10px_rgba(15,23,42,0.18)] dark:border-white/[0.08] dark:bg-white/[0.05] dark:shadow-[0_1px_0_rgba(255,255,255,0.05)_inset,0_4px_18px_-12px_rgba(0,0,0,0.5)] dark:hover:border-white/[0.12] dark:hover:bg-white/[0.07] dark:hover:shadow-[0_4px_16px_-10px_rgba(0,0,0,0.55)] focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-foreground/15", + "hub-skill-card skill-card-enter group flex h-full w-full cursor-pointer flex-col rounded-2xl border border-border/50 bg-background/75 p-3.5 text-left shadow-[0_1px_0_rgba(255,255,255,0.55)_inset,0_4px_18px_-12px_rgba(15,23,42,0.16)] transition-all hover:-translate-y-0.5 hover:border-border/60 hover:bg-background/85 hover:shadow-[0_4px_16px_-10px_rgba(15,23,42,0.18)] dark:border-white/[0.08] dark:bg-white/[0.05] dark:shadow-[0_1px_0_rgba(255,255,255,0.05)_inset,0_4px_18px_-12px_rgba(0,0,0,0.5)] dark:hover:border-white/[0.12] dark:hover:bg-white/[0.07] dark:hover:shadow-[0_4px_16px_-10px_rgba(0,0,0,0.55)] focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-foreground/15", bulkMode ? "cursor-default hover:translate-y-0" : null, )} > @@ -2074,7 +2074,7 @@ export function SkillsHubPage(props: SkillsHubPageProps) { }} className={cn( "hub-skill-card skill-card-enter group relative flex h-full w-full flex-col rounded-2xl border p-3.5 text-left transition-all", - "cursor-pointer backdrop-blur-xl focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-foreground/15", + "cursor-pointer focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-foreground/15", // Enabled style always visible; bulk selection overlays primary ring. checked ? "border-emerald-500/35 bg-emerald-50/90 shadow-[0_1px_0_rgba(255,255,255,0.55)_inset,0_4px_14px_-12px_rgba(16,185,129,0.28)] dark:border-emerald-400/30 dark:bg-emerald-500/12 dark:shadow-[0_1px_0_rgba(255,255,255,0.05)_inset,0_4px_14px_-12px_rgba(16,185,129,0.22)]" @@ -3408,7 +3408,7 @@ function SkillsStoreView(props: { } }} className={cn( - "skill-card-enter group flex h-full cursor-pointer flex-col rounded-2xl border p-3.5 text-left backdrop-blur-xl transition-all focus:outline-none focus:ring-2 focus:ring-foreground/10", + "skill-card-enter group flex h-full cursor-pointer flex-col rounded-2xl border p-3.5 text-left transition-all focus:outline-none focus:ring-2 focus:ring-foreground/10", done ? "border-border/55 bg-background/80 shadow-[0_1px_0_rgba(255,255,255,0.6)_inset,0_4px_18px_-12px_rgba(15,23,42,0.18)] dark:border-white/[0.10] dark:bg-white/[0.07] dark:shadow-[0_1px_0_rgba(255,255,255,0.07)_inset,0_4px_18px_-12px_rgba(0,0,0,0.55)]" : "border-border/40 bg-background/60 hover:-translate-y-0.5 hover:border-border/55 hover:bg-background/75 hover:shadow-[0_4px_16px_-10px_rgba(15,23,42,0.18)] dark:border-white/[0.05] dark:bg-white/[0.03] dark:hover:border-white/[0.10] dark:hover:bg-white/[0.06] dark:hover:shadow-[0_4px_16px_-10px_rgba(0,0,0,0.55)]", From 5237b04b97096c17290af12ab3ec85eeb63f91c9 Mon Sep 17 00:00:00 2001 From: AlphaCat Date: Tue, 21 Jul 2026 02:48:50 +0800 Subject: [PATCH 2/3] =?UTF-8?q?style(skills-hub):=20=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E5=86=97=E4=BD=99=E6=B8=B2=E6=9F=93=E7=89=87=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/src/pages/skills-hub/SkillsHubPage.tsx | 6 ++---- crates/agent-gui/src/pages/skills-hub/SkillsHubPage.tsx | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/crates/agent-gateway/web/src/pages/skills-hub/SkillsHubPage.tsx b/crates/agent-gateway/web/src/pages/skills-hub/SkillsHubPage.tsx index afc84b86a..f65044f93 100644 --- a/crates/agent-gateway/web/src/pages/skills-hub/SkillsHubPage.tsx +++ b/crates/agent-gateway/web/src/pages/skills-hub/SkillsHubPage.tsx @@ -1607,8 +1607,7 @@ export function SkillsHubPage(props: SkillsHubPageProps) { ) : ( - <> - {view === "installed" ? ( + view === "installed" ? (
void rescanExternalSkills()} onImport={() => void importSelectedExternalSkills()} /> - )} - + ) )}
diff --git a/crates/agent-gui/src/pages/skills-hub/SkillsHubPage.tsx b/crates/agent-gui/src/pages/skills-hub/SkillsHubPage.tsx index 1d76f8ede..bb177c8bf 100644 --- a/crates/agent-gui/src/pages/skills-hub/SkillsHubPage.tsx +++ b/crates/agent-gui/src/pages/skills-hub/SkillsHubPage.tsx @@ -1694,8 +1694,7 @@ export function SkillsHubPage(props: SkillsHubPageProps) { ) : ( - <> - {view === "installed" ? ( + view === "installed" ? (
void rescanExternalSkills()} onImport={() => void importSelectedExternalSkills()} /> - )} - + ) )}
From 3d7a0cfcbd1bb21381622144c63800b6eb321e06 Mon Sep 17 00:00:00 2001 From: AlphaCat Date: Tue, 21 Jul 2026 03:03:44 +0800 Subject: [PATCH 3/3] =?UTF-8?q?style(skills-hub):=20=E5=AF=B9=E9=BD=90?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6=E6=B8=B2=E6=9F=93=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/skills-hub/SkillsHubPage.tsx | 794 +++++++++-------- .../src/pages/skills-hub/SkillsHubPage.tsx | 833 +++++++++--------- 2 files changed, 807 insertions(+), 820 deletions(-) diff --git a/crates/agent-gateway/web/src/pages/skills-hub/SkillsHubPage.tsx b/crates/agent-gateway/web/src/pages/skills-hub/SkillsHubPage.tsx index f65044f93..ce17272c3 100644 --- a/crates/agent-gateway/web/src/pages/skills-hub/SkillsHubPage.tsx +++ b/crates/agent-gateway/web/src/pages/skills-hub/SkillsHubPage.tsx @@ -1606,440 +1606,432 @@ export function SkillsHubPage(props: SkillsHubPageProps) { - ) : ( - view === "installed" ? ( -
-
- {loadError ? ( - -
- - {loadError} -
-
- ) : null} + ) : view === "installed" ? ( +
+
+ {loadError ? ( + +
+ + {loadError} +
+
+ ) : null} - {!skillsEnabled ? ( - -
- - - {t("settings.skillsDisabledHint")} - -
-
- ) : null} + {!skillsEnabled ? ( + +
+ + + {t("settings.skillsDisabledHint")} + +
+
+ ) : null} - {!loading && skills.length === 0 && !loadError ? ( - -
-
- + {!loading && skills.length === 0 && !loadError ? ( + +
+
+ +
+
+

+ {t("settings.skillsNotFound")} +

+

+ {t("settings.skillsNotFoundHint")} +

+
+ +
+
+ ) : null} + + {loading && skills.length === 0 ? ( + <> +
+
+ +
+
+ {t("settings.skillsScanning")}
-
-

- {t("settings.skillsNotFound")} -

-

- {t("settings.skillsNotFoundHint")} -

+
+ {t("settings.skillsHubScanning")}
-
- - ) : null} +
+
+
- {loading && skills.length === 0 ? ( - <> -
-
- -
-
- {t("settings.skillsScanning")} -
-
- {t("settings.skillsHubScanning")} -
+
+ {[1, 2, 3, 4, 5, 6].map((item) => ( +
+
+
+
+
+
-
+ ))} +
+ + ) : null} -
- {[1, 2, 3, 4, 5, 6].map((item) => ( -
-
-
-
-
-
-
-
-
- ))} -
- + {filtered.length > 0 ? ( +
+ {bulkMode ? ( +
+ + {t("settings.skillsBulkHint")} +
) : null} +
+ {filtered.map((skill) => { + const alwaysEnabled = isAlwaysEnabledSkillName(skill.name); + const checked = alwaysEnabled || selected.has(skill.name); + const bulkSelected = bulkSelection.has(skill.name); + const deleting = deletingSkillName === skill.name; + const deleteDisabled = deletingSkillName !== null; + const card = ( + <> +
+
+ +
- {filtered.length > 0 ? ( -
- {bulkMode ? ( -
- - {t("settings.skillsBulkHint")} -
- ) : null} -
- {filtered.map((skill) => { - const alwaysEnabled = isAlwaysEnabledSkillName(skill.name); - const checked = alwaysEnabled || selected.has(skill.name); - const bulkSelected = bulkSelection.has(skill.name); - const deleting = deletingSkillName === skill.name; - const deleteDisabled = deletingSkillName !== null; - const card = ( - <> -
+ {alwaysEnabled && !bulkMode ? ( +
+ + {t("settings.skillsAlwaysOn")} +
+ ) : bulkMode ? ( + alwaysEnabled ? (
- -
- - {alwaysEnabled && !bulkMode ? ( - - ) : bulkMode ? ( - alwaysEnabled ? ( -
- -
- ) : ( -
event.stopPropagation()} - onKeyDown={(event) => event.stopPropagation()} - > - -
- ) - ) : ( -
event.stopPropagation()} - onKeyDown={(event) => event.stopPropagation()} + +
+ ) : ( +
event.stopPropagation()} + onKeyDown={(event) => event.stopPropagation()} + > + +
+ ) + ) : ( +
event.stopPropagation()} + onKeyDown={(event) => event.stopPropagation()} + > + + +
+ )} +
+ +
+
+
+ {skill.name} +
+ {checked ? ( + + {t("settings.skillsHubEnabledBadge")} + + ) : null} +
+ {skill.description ? ( +

+ {skill.description} +

+ ) : null} +
+ +
+ + {skill.skillFile} + {!alwaysEnabled && !bulkMode ? ( +
event.stopPropagation()} + onKeyDown={(event) => event.stopPropagation()} + > + void deleteSkill(skill)} + > + {(open) => ( -
- )} -
- -
-
-
- {skill.name} -
- {checked ? ( - - {t("settings.skillsHubEnabledBadge")} - - ) : null} -
- {skill.description ? ( -

- {skill.description} -

- ) : null} -
- -
- - {skill.skillFile} - {!alwaysEnabled && !bulkMode ? ( -
event.stopPropagation()} - onKeyDown={(event) => event.stopPropagation()} - > - void deleteSkill(skill)} - > - {(open) => ( - + {deleting ? ( + + ) : ( + )} - -
- ) : null} + + )} +
- - ); - - const key = `${skill.name}-${rootDir}`; - if (alwaysEnabled) { - return ( - - ); - } + ) : null} +
+ + ); - return ( - // biome-ignore lint/a11y/useSemanticElements: The card contains nested controls and cannot be a native button. -
{ - if (bulkMode) { - handleBulkInstalledCardClick( - skill.name, - filtered.map((item) => item.name), - event.shiftKey, - ); - return; - } - openInstalledSkillPreview(skill); - }} - onMouseDown={(event) => { - if (bulkMode && event.shiftKey) event.preventDefault(); - }} - onKeyDown={(event) => { - if ( - bulkMode && - (event.key === "Enter" || event.key === " ") - ) { - event.preventDefault(); - handleBulkInstalledCardClick( - skill.name, - filtered.map((item) => item.name), - event.shiftKey, - ); - return; - } - handleInstalledSkillCardKeyDown(event, skill); - }} - className={cn( - "hub-skill-card skill-card-enter group relative flex h-full w-full flex-col rounded-2xl border p-3.5 text-left transition-all", - "cursor-pointer focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-foreground/15", - checked - ? "border-emerald-500/35 bg-emerald-50/90 shadow-[0_1px_0_rgba(255,255,255,0.55)_inset,0_4px_14px_-12px_rgba(16,185,129,0.28)] dark:border-emerald-400/30 dark:bg-emerald-500/12 dark:shadow-[0_1px_0_rgba(255,255,255,0.05)_inset,0_4px_14px_-12px_rgba(16,185,129,0.22)]" - : "border-border/40 bg-muted/45 text-muted-foreground shadow-none hover:-translate-y-0.5 hover:border-border/55 hover:bg-muted/55 dark:border-white/[0.06] dark:bg-white/[0.025] dark:hover:border-white/[0.10] dark:hover:bg-white/[0.04]", - bulkSelected - ? "ring-2 ring-primary/50 ring-offset-1 ring-offset-background" - : null, - )} - > - {card} -
- ); - })} -
-
- ) : null} + const key = `${skill.name}-${rootDir}`; + if (alwaysEnabled) { + return ( + + ); + } - {filter.trim() && filtered.length === 0 && skills.length > 0 ? ( - -

- {t("settings.skillsNoMatch").replace("{filter}", filter)} -

-
- ) : null} + return ( + // biome-ignore lint/a11y/useSemanticElements: The card contains nested controls and cannot be a native button. +
{ + if (bulkMode) { + handleBulkInstalledCardClick( + skill.name, + filtered.map((item) => item.name), + event.shiftKey, + ); + return; + } + openInstalledSkillPreview(skill); + }} + onMouseDown={(event) => { + if (bulkMode && event.shiftKey) event.preventDefault(); + }} + onKeyDown={(event) => { + if (bulkMode && (event.key === "Enter" || event.key === " ")) { + event.preventDefault(); + handleBulkInstalledCardClick( + skill.name, + filtered.map((item) => item.name), + event.shiftKey, + ); + return; + } + handleInstalledSkillCardKeyDown(event, skill); + }} + className={cn( + "hub-skill-card skill-card-enter group relative flex h-full w-full flex-col rounded-2xl border p-3.5 text-left transition-all", + "cursor-pointer focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-foreground/15", + checked + ? "border-emerald-500/35 bg-emerald-50/90 shadow-[0_1px_0_rgba(255,255,255,0.55)_inset,0_4px_14px_-12px_rgba(16,185,129,0.28)] dark:border-emerald-400/30 dark:bg-emerald-500/12 dark:shadow-[0_1px_0_rgba(255,255,255,0.05)_inset,0_4px_14px_-12px_rgba(16,185,129,0.22)]" + : "border-border/40 bg-muted/45 text-muted-foreground shadow-none hover:-translate-y-0.5 hover:border-border/55 hover:bg-muted/55 dark:border-white/[0.06] dark:bg-white/[0.025] dark:hover:border-white/[0.10] dark:hover:bg-white/[0.04]", + bulkSelected + ? "ring-2 ring-primary/50 ring-offset-1 ring-offset-background" + : null, + )} + > + {card} +
+ ); + })} +
-
- ) : view === "store" ? ( - void loadMoreStore()} - onInstall={(skill) => void installStoreSkill(skill)} - /> - ) : ( - { - if (importToastTimerRef.current !== null) { - window.clearTimeout(importToastTimerRef.current); - importToastTimerRef.current = null; - } - setImportToast(null); - }} - bulkMode={bulkMode} - onToggle={toggleExternalSkill} - onBatchToggle={setExternalSkillsSelected} - onRescan={() => void rescanExternalSkills()} - onImport={() => void importSelectedExternalSkills()} - /> - ) + ) : null} + + {filter.trim() && filtered.length === 0 && skills.length > 0 ? ( + +

+ {t("settings.skillsNoMatch").replace("{filter}", filter)} +

+
+ ) : null} +
+
+ ) : view === "store" ? ( + void loadMoreStore()} + onInstall={(skill) => void installStoreSkill(skill)} + /> + ) : ( + { + if (importToastTimerRef.current !== null) { + window.clearTimeout(importToastTimerRef.current); + importToastTimerRef.current = null; + } + setImportToast(null); + }} + bulkMode={bulkMode} + onToggle={toggleExternalSkill} + onBatchToggle={setExternalSkillsSelected} + onRescan={() => void rescanExternalSkills()} + onImport={() => void importSelectedExternalSkills()} + /> )}
@@ -2059,9 +2051,9 @@ export function SkillsHubPage(props: SkillsHubPageProps) { ) : null} {bulkMode && - view === "installed" && - !lockedByChatMode && - (!bulkUndo || bulkSelection.size > 0) ? ( + view === "installed" && + !lockedByChatMode && + (!bulkUndo || bulkSelection.size > 0) ? (
{bulkSelection.size > 0 ? ( diff --git a/crates/agent-gui/src/pages/skills-hub/SkillsHubPage.tsx b/crates/agent-gui/src/pages/skills-hub/SkillsHubPage.tsx index bb177c8bf..8feac8956 100644 --- a/crates/agent-gui/src/pages/skills-hub/SkillsHubPage.tsx +++ b/crates/agent-gui/src/pages/skills-hub/SkillsHubPage.tsx @@ -1693,460 +1693,455 @@ export function SkillsHubPage(props: SkillsHubPageProps) {
- ) : ( - view === "installed" ? ( -
-
- {skills.length > 0 ? ( - - ) : null} + ) : view === "installed" ? ( +
+
+ {skills.length > 0 ? ( + + ) : null} - {bulkMode ? ( -
- - {t("settings.skillsBulkHint")} -
- ) : null} + {bulkMode ? ( +
+ + {t("settings.skillsBulkHint")} +
+ ) : null} - {loadError ? ( - -
- - {loadError} -
-
- ) : null} + {loadError ? ( + +
+ + {loadError} +
+
+ ) : null} - {!skillsEnabled ? ( - -
- - - {t("settings.skillsDisabledHint")} - -
-
- ) : null} + {!skillsEnabled ? ( + +
+ + + {t("settings.skillsDisabledHint")} + +
+
+ ) : null} + + {!loading && skills.length === 0 && !loadError ? ( + +
+
+ +
+
+

+ {t("settings.skillsNotFound")} +

+

+ {t("settings.skillsNotFoundHint")} +

+
+ +
+
+ ) : null} - {!loading && skills.length === 0 && !loadError ? ( - -
-
- + {loading && skills.length === 0 ? ( + <> +
+
+ +
+
+ {t("settings.skillsScanning")}
-
-

- {t("settings.skillsNotFound")} -

-

- {t("settings.skillsNotFoundHint")} -

+
+ {t("settings.skillsHubScanning")}
-
- - ) : null} +
+
+
- {loading && skills.length === 0 ? ( - <> -
-
- -
-
- {t("settings.skillsScanning")} -
-
- {t("settings.skillsHubScanning")} -
+
+ {[1, 2, 3, 4, 5, 6].map((item) => ( +
+
+
+
+
+
-
+ ))} +
+ + ) : null} -
- {[1, 2, 3, 4, 5, 6].map((item) => ( + {filtered.length > 0 ? ( +
+ {filtered.map(({ skill, categories }) => { + const alwaysEnabled = isAlwaysEnabledSkillName(skill.name); + const checked = alwaysEnabled || selected.has(skill.name); + const bulkSelected = bulkSelection.has(skill.name); + const deleting = deletingSkillName === skill.name; + const deleteDisabled = deletingSkillName !== null; + const PrimaryCategoryIcon = + STORE_CATEGORY_ICONS[categories[0] ?? "other"]; + const card = ( + <> +
-
-
-
-
-
-
-
+
- ))} -
- - ) : null} - {filtered.length > 0 ? ( -
- {filtered.map(({ skill, categories }) => { - const alwaysEnabled = isAlwaysEnabledSkillName(skill.name); - const checked = alwaysEnabled || selected.has(skill.name); - const bulkSelected = bulkSelection.has(skill.name); - const deleting = deletingSkillName === skill.name; - const deleteDisabled = deletingSkillName !== null; - const PrimaryCategoryIcon = - STORE_CATEGORY_ICONS[categories[0] ?? "other"]; - const card = ( - <> -
+ {alwaysEnabled && !bulkMode ? ( +
+ + {t("settings.skillsAlwaysOn")} +
+ ) : bulkMode ? ( + alwaysEnabled ? (
- -
- - {alwaysEnabled && !bulkMode ? ( - - ) : bulkMode ? ( - alwaysEnabled ? ( -
- -
- ) : ( -
event.stopPropagation()} - onKeyDown={(event) => event.stopPropagation()} - > - -
- ) - ) : ( -
event.stopPropagation()} - onKeyDown={(event) => event.stopPropagation()} + +
+ ) : ( +
event.stopPropagation()} + onKeyDown={(event) => event.stopPropagation()} + > + +
+ ) + ) : ( +
event.stopPropagation()} + onKeyDown={(event) => event.stopPropagation()} + > + + +
+ )} +
+ +
+
+
+ {skill.name} +
+ {checked ? ( + + {t("settings.skillsHubEnabledBadge")} + + ) : null} +
+ {skill.description ? ( +

+ {skill.description} +

+ ) : null} + {!alwaysEnabled ? ( +
+ +
+ ) : null} +
+ +
+ + {skill.skillFile} + {!alwaysEnabled && !bulkMode ? ( +
event.stopPropagation()} + onKeyDown={(event) => event.stopPropagation()} + > + void deleteSkill(skill)} + > + {(open) => ( -
- )} -
- -
-
-
- {skill.name} -
- {checked ? ( - - {t("settings.skillsHubEnabledBadge")} - - ) : null} -
- {skill.description ? ( -

- {skill.description} -

- ) : null} - {!alwaysEnabled ? ( -
- -
- ) : null} -
- -
- - {skill.skillFile} - {!alwaysEnabled && !bulkMode ? ( -
event.stopPropagation()} - onKeyDown={(event) => event.stopPropagation()} - > - void deleteSkill(skill)} - > - {(open) => ( - + {deleting ? ( + + ) : ( + )} - -
- ) : null} + + )} +
- - ); - - const key = `${skill.name}-${rootDir}`; - if (alwaysEnabled) { - return ( - - ); - } - - return ( - // biome-ignore lint/a11y/useSemanticElements: The card contains nested controls and cannot be a native button. -
{ - if (bulkMode) { - handleBulkInstalledCardClick( - skill.name, - filtered.map((entry) => entry.skill.name), - event.shiftKey, - ); - return; - } - openInstalledSkillPreview(skill); - }} - onMouseDown={(event) => { - // Shift+点击做区间选择时避免浏览器拖出文本选区 - if (bulkMode && event.shiftKey) event.preventDefault(); - }} - onKeyDown={(event) => { - if (bulkMode && (event.key === "Enter" || event.key === " ")) { - event.preventDefault(); - handleBulkInstalledCardClick( - skill.name, - filtered.map((entry) => entry.skill.name), - event.shiftKey, - ); - return; - } - handleInstalledSkillCardKeyDown(event, skill); - }} - className={cn( - "hub-skill-card skill-card-enter group relative flex h-full w-full flex-col rounded-2xl border p-3.5 text-left transition-all", - "cursor-pointer focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-foreground/15", - // Enabled style always visible; bulk selection overlays primary ring. - checked - ? "border-emerald-500/35 bg-emerald-50/90 shadow-[0_1px_0_rgba(255,255,255,0.55)_inset,0_4px_14px_-12px_rgba(16,185,129,0.28)] dark:border-emerald-400/30 dark:bg-emerald-500/12 dark:shadow-[0_1px_0_rgba(255,255,255,0.05)_inset,0_4px_14px_-12px_rgba(16,185,129,0.22)]" - : "border-border/40 bg-muted/45 text-muted-foreground shadow-none hover:-translate-y-0.5 hover:border-border/55 hover:bg-muted/55 dark:border-white/[0.06] dark:bg-white/[0.025] dark:hover:border-white/[0.10] dark:hover:bg-white/[0.04]", - bulkSelected - ? "ring-2 ring-primary/50 ring-offset-1 ring-offset-background" - : null, - )} - > - {card} -
- ); - })} -
- ) : null} - - {(filter.trim() || installedCategory !== "all") && - filtered.length === 0 && - skills.length > 0 ? ( - -

- {filter.trim() - ? t("settings.skillsNoMatch").replace("{filter}", filter) - : t("settings.skillsStoreEmptyTitle")} -

-
- ) : null} + ) : null} +
+ + ); + + const key = `${skill.name}-${rootDir}`; + if (alwaysEnabled) { + return ( + + ); + } + + return ( + // biome-ignore lint/a11y/useSemanticElements: The card contains nested controls and cannot be a native button. +
{ + if (bulkMode) { + handleBulkInstalledCardClick( + skill.name, + filtered.map((entry) => entry.skill.name), + event.shiftKey, + ); + return; + } + openInstalledSkillPreview(skill); + }} + onMouseDown={(event) => { + // Shift+点击做区间选择时避免浏览器拖出文本选区 + if (bulkMode && event.shiftKey) event.preventDefault(); + }} + onKeyDown={(event) => { + if (bulkMode && (event.key === "Enter" || event.key === " ")) { + event.preventDefault(); + handleBulkInstalledCardClick( + skill.name, + filtered.map((entry) => entry.skill.name), + event.shiftKey, + ); + return; + } + handleInstalledSkillCardKeyDown(event, skill); + }} + className={cn( + "hub-skill-card skill-card-enter group relative flex h-full w-full flex-col rounded-2xl border p-3.5 text-left transition-all", + "cursor-pointer focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-foreground/15", + // Enabled style always visible; bulk selection overlays primary ring. + checked + ? "border-emerald-500/35 bg-emerald-50/90 shadow-[0_1px_0_rgba(255,255,255,0.55)_inset,0_4px_14px_-12px_rgba(16,185,129,0.28)] dark:border-emerald-400/30 dark:bg-emerald-500/12 dark:shadow-[0_1px_0_rgba(255,255,255,0.05)_inset,0_4px_14px_-12px_rgba(16,185,129,0.22)]" + : "border-border/40 bg-muted/45 text-muted-foreground shadow-none hover:-translate-y-0.5 hover:border-border/55 hover:bg-muted/55 dark:border-white/[0.06] dark:bg-white/[0.025] dark:hover:border-white/[0.10] dark:hover:bg-white/[0.04]", + bulkSelected + ? "ring-2 ring-primary/50 ring-offset-1 ring-offset-background" + : null, + )} + > + {card} +
+ ); + })}
-
- ) : view === "store" ? ( - void loadMoreStore()} - onInstall={(skill) => void installStoreSkill(skill)} - /> - ) : ( - { - if (importToastTimerRef.current !== null) { - window.clearTimeout(importToastTimerRef.current); - importToastTimerRef.current = null; - } - setImportToast(null); - }} - bulkMode={bulkMode} - onToggle={toggleExternalSkill} - onBatchToggle={batchToggleExternalSkills} - onRescan={() => void rescanExternalSkills()} - onImport={() => void importSelectedExternalSkills()} - /> - ) + ) : null} + + {(filter.trim() || installedCategory !== "all") && + filtered.length === 0 && + skills.length > 0 ? ( + +

+ {filter.trim() + ? t("settings.skillsNoMatch").replace("{filter}", filter) + : t("settings.skillsStoreEmptyTitle")} +

+
+ ) : null} +
+
+ ) : view === "store" ? ( + void loadMoreStore()} + onInstall={(skill) => void installStoreSkill(skill)} + /> + ) : ( + { + if (importToastTimerRef.current !== null) { + window.clearTimeout(importToastTimerRef.current); + importToastTimerRef.current = null; + } + setImportToast(null); + }} + bulkMode={bulkMode} + onToggle={toggleExternalSkill} + onBatchToggle={batchToggleExternalSkills} + onRescan={() => void rescanExternalSkills()} + onImport={() => void importSelectedExternalSkills()} + /> )}
@@ -2166,9 +2161,9 @@ export function SkillsHubPage(props: SkillsHubPageProps) { ) : null} {bulkMode && - view === "installed" && - !lockedByChatMode && - (!bulkUndo || bulkSelection.size > 0) ? ( + view === "installed" && + !lockedByChatMode && + (!bulkUndo || bulkSelection.size > 0) ? (
{bulkSelection.size > 0 ? (