diff --git a/src/client/apes/icons.tsx b/src/client/apes/icons.tsx index 47e3a2e..5b89d43 100644 --- a/src/client/apes/icons.tsx +++ b/src/client/apes/icons.tsx @@ -1,51 +1,50 @@ /** - * Custom fill-style icons for apes tabs — matching the visual weight of - * DSH native tabs (which use `fill: currentColor` paths, not outline/mask). + * Tab glyphs for the apes tabs (智能体 / 应用 / 画像). * - * DSH's `@deepseek-ai/dsh-client-ui-primitives` only ships outline variants - * for agent/gauge/user, so we define our own fill variants here to ensure - * the apes tabs look "official" in the + menu. + * These follow the SAME recipe as this repo's own icon set in + * `src/client/icons.tsx` — the one the sidebar already uses for 终端 / + * 浏览器 / 文件变动: a 16×16 viewBox whose artwork spans 1.5–14.5, a 1.5px + * `currentColor` stroke, round caps/joins, `fill: none`. + * + * That recipe is what makes an icon sit at the native visual weight in the + * `+` new-tab menu and the right-panel tile grid: DSH's own glyphs fill + * ~92–96% of the box, so artwork padded any tighter renders visibly small + * next to them. + * + * (An earlier revision drew these as fill-only paths spanning only 10–12 of + * the 16 units — that is why they read as a separate, lighter family.) */ import type { ReactNode } from 'react' -/** Agent icon: a simple robot/agent face (fill style). */ -export function IconAgentFill16({ size = 16, className }: { size?: number; className?: string }): ReactNode { +/** Agent glyph: a rounded robot head with two fill eyes. */ +export function IconAgentOutline16({ size = 16, className }: { size?: number; className?: string }): ReactNode { return ( - + + + ) } -/** Gauge/app icon: a simple app grid (fill style). */ -export function IconGaugeFill16({ size = 16, className }: { size?: number; className?: string }): ReactNode { +/** Apps glyph: a 2×2 grid of rounded squares. */ +export function IconAppsOutline16({ size = 16, className }: { size?: number; className?: string }): ReactNode { return ( - + + + + ) } -/** User/profile icon: a simple user silhouette (fill style). */ -export function IconUserFill16({ size = 16, className }: { size?: number; className?: string }): ReactNode { +/** Profile glyph: a head over shoulders. */ +export function IconUserOutline16({ size = 16, className }: { size?: number; className?: string }): ReactNode { return ( - + + ) } diff --git a/src/client/apes/tabs.tsx b/src/client/apes/tabs.tsx index 1ce232a..2eb292b 100644 --- a/src/client/apes/tabs.tsx +++ b/src/client/apes/tabs.tsx @@ -26,7 +26,7 @@ */ import { useCallback, useMemo, useState, type CSSProperties } from 'react' import { useSyncExternalStore } from 'react' -import { IconAgentFill16, IconGaugeFill16, IconUserFill16 } from './icons.tsx' +import { IconAgentOutline16, IconAppsOutline16, IconUserOutline16 } from './icons.tsx' import type { TabComponentProps, TabDescriptor } from '../service.ts' import type { SidebarSessionList, @@ -231,7 +231,7 @@ function ApesAppsView(props: TabComponentProps) { * to `service.registerTab`. Information-layer tabs are single-instance. */ export const apesTabs: TabDescriptor[] = [ - { id: 'apes:agents', title: () => t('apesAgentsTitle'), icon: (size: number) => , order: 60, single: true, component: ApesAgentsView }, - { id: 'apes:apps', title: () => t('apesAppsTitle'), icon: (size: number) => , order: 65, single: true, component: ApesAppsView }, - { id: 'apes:profile', title: () => t('apesProfileTitle'), icon: (size: number) => , order: 70, single: true, component: ApesProfileView }, + { id: 'apes:agents', title: () => t('apesAgentsTitle'), icon: (size: number) => , order: 60, single: true, component: ApesAgentsView }, + { id: 'apes:apps', title: () => t('apesAppsTitle'), icon: (size: number) => , order: 65, single: true, component: ApesAppsView }, + { id: 'apes:profile', title: () => t('apesProfileTitle'), icon: (size: number) => , order: 70, single: true, component: ApesProfileView }, ]