diff --git a/web/src/components/ui/aceternity/hover-border-gradient.tsx b/web/src/components/ui/aceternity/hover-border-gradient.tsx index 019893382..2091a07dc 100644 --- a/web/src/components/ui/aceternity/hover-border-gradient.tsx +++ b/web/src/components/ui/aceternity/hover-border-gradient.tsx @@ -24,25 +24,13 @@ const movingMap: Record = { const highlight = "radial-gradient(75% 181% at 50% 50%, color-mix(in srgb, var(--user-ink) 22%, transparent) 0%, transparent 100%)"; function rotateDirection(current: Direction, clockwise: boolean): Direction { - const directions: Direction[] = clockwise - ? ["TOP", "LEFT", "BOTTOM", "RIGHT"] - : ["TOP", "RIGHT", "BOTTOM", "LEFT"]; + const directions: Direction[] = clockwise ? ["TOP", "LEFT", "BOTTOM", "RIGHT"] : ["TOP", "RIGHT", "BOTTOM", "LEFT"]; const index = directions.indexOf(current); return directions[(index - 1 + directions.length) % directions.length]; } // Aceternity Hover Border Gradient:中性墨色描边,不用彩色高光。 -export function HoverBorderGradient({ - children, - containerClassName, - className, - as, - duration = 1, - clockwise = true, - onMouseEnter, - onMouseLeave, - ...props -}: HoverBorderGradientProps) { +export function HoverBorderGradient({ children, containerClassName, className, as, duration = 1, clockwise = true, onMouseEnter, onMouseLeave, ...props }: HoverBorderGradientProps) { const Tag = (as || "button") as any; const reducedMotion = useReducedMotion(); const [hovered, setHovered] = useState(false); diff --git a/web/src/lib/sidebar-checkin.ts b/web/src/lib/sidebar-checkin.ts index 78d89b692..93cbaf79c 100644 --- a/web/src/lib/sidebar-checkin.ts +++ b/web/src/lib/sidebar-checkin.ts @@ -1,8 +1,4 @@ -export function shouldShowSidebarCheckin(input: { - creditsEnabled?: boolean; - checkinBonusMicrocredits?: number | null; - checkedInToday?: boolean; -}) { +export function shouldShowSidebarCheckin(input: { creditsEnabled?: boolean; checkinBonusMicrocredits?: number | null; checkedInToday?: boolean }) { return Boolean(input.creditsEnabled && (input.checkinBonusMicrocredits || 0) > 0 && !input.checkedInToday); } diff --git a/web/src/pages/admin/components/agent-lessons-panel.tsx b/web/src/pages/admin/components/agent-lessons-panel.tsx index e2fe1c518..742c94f05 100644 --- a/web/src/pages/admin/components/agent-lessons-panel.tsx +++ b/web/src/pages/admin/components/agent-lessons-panel.tsx @@ -179,9 +179,7 @@ export default function AgentLessonsPanel() { return (
-

- 记忆归用户自己批准和管理。这里只做巡查:可按用户、状态、关键词筛选,必要时删除违规内容。批准入口在用户的「设置 → Agent 记忆」。 -

+

记忆归用户自己批准和管理。这里只做巡查:可按用户、状态、关键词筛选,必要时删除违规内容。批准入口在用户的「设置 → Agent 记忆」。

@@ -211,13 +209,7 @@ export default function AgentLessonsPanel() { label: user.displayName ? `${user.displayName}(${user.username})` : user.username, }))} /> - setKeyword(event.target.value)} - /> + setKeyword(event.target.value)} /> diff --git a/web/src/pages/admin/theme/admin-chrome.css b/web/src/pages/admin/theme/admin-chrome.css index a47aff090..0c639784c 100644 --- a/web/src/pages/admin/theme/admin-chrome.css +++ b/web/src/pages/admin/theme/admin-chrome.css @@ -142,7 +142,9 @@ font-weight: 500; line-height: 16px; text-decoration: none; - transition: background-color var(--admin-motion), color var(--admin-motion); + transition: + background-color var(--admin-motion), + color var(--admin-motion); } [data-admin-root] .admin-nav-link.is-collapsed { @@ -651,18 +653,19 @@ padding: 4px 0; } -[data-admin-root] :is( - .admin-feature-command-bar, - .admin-appearance-command-bar, - .admin-access-command-bar, - .admin-email-command-bar, - .admin-storage-command-bar, - .admin-ark-command-bar, - .admin-intercept-command-bar, - .admin-drawing-command-bar, - .admin-runtime-policy-command-bar, - .admin-third-party-command-bar -) { +[data-admin-root] + :is( + .admin-feature-command-bar, + .admin-appearance-command-bar, + .admin-access-command-bar, + .admin-email-command-bar, + .admin-storage-command-bar, + .admin-ark-command-bar, + .admin-intercept-command-bar, + .admin-drawing-command-bar, + .admin-runtime-policy-command-bar, + .admin-third-party-command-bar + ) { position: sticky; top: 0; z-index: 8; @@ -681,26 +684,24 @@ backdrop-filter: none !important; } -[data-admin-root] :is( - .admin-feature-command-bar, - .admin-appearance-command-bar, - .admin-access-command-bar, - .admin-email-command-bar, - .admin-storage-command-bar, - .admin-ark-command-bar, - .admin-intercept-command-bar, - .admin-drawing-command-bar, - .admin-runtime-policy-command-bar, - .admin-third-party-command-bar -).is-dirty { +[data-admin-root] + :is( + .admin-feature-command-bar, + .admin-appearance-command-bar, + .admin-access-command-bar, + .admin-email-command-bar, + .admin-storage-command-bar, + .admin-ark-command-bar, + .admin-intercept-command-bar, + .admin-drawing-command-bar, + .admin-runtime-policy-command-bar, + .admin-third-party-command-bar + ).is-dirty { border-bottom-color: color-mix(in srgb, var(--admin-status-warning) 55%, var(--admin-border)) !important; background: color-mix(in srgb, var(--admin-status-warning) 8%, var(--admin-canvas)) !important; } -[data-admin-root] :is( - .admin-feature-command-copy strong, - .admin-appearance-command-copy strong -) { +[data-admin-root] :is(.admin-feature-command-copy strong, .admin-appearance-command-copy strong) { color: var(--admin-text); font-size: 12px; font-weight: 650; diff --git a/web/src/pages/admin/theme/admin-tokens.css b/web/src/pages/admin/theme/admin-tokens.css index 26279f76e..b0fb09242 100644 --- a/web/src/pages/admin/theme/admin-tokens.css +++ b/web/src/pages/admin/theme/admin-tokens.css @@ -2,15 +2,7 @@ * Never alias --workspace-*, --user-*, or --skin-* from the product UI. * Light/dark follow the page theme class; product skins are ignored. */ -:is( - [data-admin-root], - body.admin-overlays, - .admin-drawer, - .admin-secondary-drawer, - .admin-modal-root, - .admin-channel-modal-root, - .admin-mobile-navigation-menu -) { +:is([data-admin-root], body.admin-overlays, .admin-drawer, .admin-secondary-drawer, .admin-modal-root, .admin-channel-modal-root, .admin-mobile-navigation-menu) { --admin-font: ui-sans-serif, "SF Pro Text", "PingFang SC", "Hiragino Sans GB", "Noto Sans SC", system-ui, sans-serif; --admin-font-mono: ui-monospace, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", monospace; --admin-space: 8px; @@ -100,17 +92,12 @@ font-family: var(--admin-font); font-size: 13px; line-height: 1.45; - font-feature-settings: "ss01" 0, "cv11" 0; + font-feature-settings: + "ss01" 0, + "cv11" 0; } -.dark :is( - [data-admin-root], - .admin-drawer, - .admin-secondary-drawer, - .admin-modal-root, - .admin-channel-modal-root, - .admin-mobile-navigation-menu -), +.dark :is([data-admin-root], .admin-drawer, .admin-secondary-drawer, .admin-modal-root, .admin-channel-modal-root, .admin-mobile-navigation-menu), .dark body.admin-overlays { --admin-canvas: #0f0f0f; --admin-sidebar: #0f0f0f; diff --git a/web/src/pages/admin/ui/controls.tsx b/web/src/pages/admin/ui/controls.tsx index bd56291b3..4d1e00ec3 100644 --- a/web/src/pages/admin/ui/controls.tsx +++ b/web/src/pages/admin/ui/controls.tsx @@ -22,14 +22,7 @@ export function AdminSwitch({ className?: string; "aria-label"?: string; }) { - return ( - props.onChange?.(checked)} - /> - ); + return props.onChange?.(checked)} />; } export function Switch(props: Parameters[0]) { @@ -53,15 +46,7 @@ export function AdminSelect({ ariaLabel?: string; className?: string; }) { - return ( - onChange?.(value as V)} - /> - ); + return onChange?.(value as V)} />; } export function Select(props: Parameters>[0]) { @@ -143,15 +128,7 @@ export function AdminSegmented({ ariaLabel?: string; className?: string; }) { - return ( - ({ ...option, label: option.label ?? option.value }))} - onChange={(next) => onChange?.(String(next) as V)} - aria-label={ariaLabel} - /> - ); + return ({ ...option, label: option.label ?? option.value }))} onChange={(next) => onChange?.(String(next) as V)} aria-label={ariaLabel} />; } export function SegmentedControl(props: Parameters>[0]) { diff --git a/web/src/pages/admin/ui/overlays.tsx b/web/src/pages/admin/ui/overlays.tsx index f9c6c2356..dfc079b0b 100644 --- a/web/src/pages/admin/ui/overlays.tsx +++ b/web/src/pages/admin/ui/overlays.tsx @@ -30,19 +30,13 @@ function mergeFlushStyles(resolved: unknown, flush: boolean, kind: "drawer" | "m } export function AdminDrawer({ flush = false, destroyOnHidden = true, styles, className, rootClassName, ...props }: AdminDrawerProps) { - const mergedStyles = - typeof styles === "function" - ? (info: { props: DrawerProps }) => mergeFlushStyles(styles(info), flush, "drawer") - : mergeFlushStyles(styles, flush, "drawer"); + const mergedStyles = typeof styles === "function" ? (info: { props: DrawerProps }) => mergeFlushStyles(styles(info), flush, "drawer") : mergeFlushStyles(styles, flush, "drawer"); return ; } export function AdminModal({ flush = false, destroyOnHidden = true, styles, className, rootClassName, ...props }: AdminModalProps) { - const mergedStyles = - typeof styles === "function" - ? (info: { props: ModalProps }) => mergeFlushStyles(styles(info), flush, "modal") - : mergeFlushStyles(styles, flush, "modal"); + const mergedStyles = typeof styles === "function" ? (info: { props: ModalProps }) => mergeFlushStyles(styles(info), flush, "modal") : mergeFlushStyles(styles, flush, "modal"); return ; } diff --git a/web/src/pages/settings/agent-memory-pane.tsx b/web/src/pages/settings/agent-memory-pane.tsx index 0343f8430..9bc4d996d 100644 --- a/web/src/pages/settings/agent-memory-pane.tsx +++ b/web/src/pages/settings/agent-memory-pane.tsx @@ -85,11 +85,7 @@ function compactStatusLabel(settings: AgentMemoryCompactView | null) { if (settings.lastStatus === "failed") return settings.lastError || "上次压缩失败"; if (settings.lastStatus === "succeeded") { const summary = settings.summary; - const parts = [ - summary?.merged ? `合并 ${summary.merged}` : "", - summary?.rewritten ? `改写 ${summary.rewritten}` : "", - summary?.removed ? `删除 ${summary.removed}` : "", - ].filter(Boolean); + const parts = [summary?.merged ? `合并 ${summary.merged}` : "", summary?.rewritten ? `改写 ${summary.rewritten}` : "", summary?.removed ? `删除 ${summary.removed}` : ""].filter(Boolean); const when = settings.lastCompactAt ? new Date(settings.lastCompactAt).toLocaleString() : ""; return [when && `上次 ${when}`, parts.join(" · ") || "模型认为没有需要改动的条目"].filter(Boolean).join(" · "); } @@ -204,14 +200,7 @@ function AgentMemoryCompactCard({ compact = false, onApplied }: { compact?: bool
- void persist(value, model)} - /> + void persist(value, model)} />
{failed && settings?.lastError ? ( - {settings.lastError} + + {settings.lastError} + ) : statusText ? (

{statusText}

) : null} @@ -378,13 +369,7 @@ export default function AgentMemoryPane({ compact = false }: { compact?: boolean return (
- +
void onExport()} /> fileRef.current?.click()} /> @@ -422,7 +407,13 @@ export default function AgentMemoryPane({ compact = false }: { compact?: boolean className={compact ? "min-h-0 flex-1 py-8" : "min-h-[220px] py-10"} title={status === "pending" ? "没有待批准的记忆" : "还没有个人记忆"} description={status === "pending" ? "Agent 跑通任务后会把可复用做法记到这里,等你点头。" : "手动添加立刻生效,也可以等 Agent 记下后再批准。"} - action={status === "pending" ? undefined : } + action={ + status === "pending" ? undefined : ( + + ) + } /> ) : null} {!loading && items.length ? ( @@ -478,14 +469,7 @@ export default function AgentMemoryPane({ compact = false }: { compact?: boolean
) : null} - void save()} - onCancel={() => setEditorOpen(false)} - > + void save()} onCancel={() => setEditorOpen(false)}>
diff --git a/web/test/cloud-agent-plan.test.ts b/web/test/cloud-agent-plan.test.ts index 369a15cd0..8ea7a0827 100644 --- a/web/test/cloud-agent-plan.test.ts +++ b/web/test/cloud-agent-plan.test.ts @@ -49,29 +49,18 @@ describe("pendingAgentQuestion", () => { const question = { question: "选哪个模型?", options: [{ label: "H3文生视频" }, { label: "Seedance 2.5" }] }; test("有未作答的提问 → 亮面板", () => { - const messages = [ - { role: "user" }, - { role: "assistant", question }, - ]; + const messages = [{ role: "user" }, { role: "assistant", question }]; expect(pendingAgentQuestion(messages)?.question).toBe("选哪个模型?"); }); test("提问之后用户已回复 → 收起面板", () => { - const messages = [ - { role: "assistant", question }, - { role: "user" }, - ]; + const messages = [{ role: "assistant", question }, { role: "user" }]; expect(pendingAgentQuestion(messages)).toBeUndefined(); }); test("多轮提问取最新那道;旧的那道不算数", () => { const later = { question: "确认开始吗?", options: [{ label: "开始" }, { label: "再改改" }] }; - const messages = [ - { role: "assistant", question }, - { role: "user" }, - { role: "assistant", question }, - { role: "assistant", question: later }, - ]; + const messages = [{ role: "assistant", question }, { role: "user" }, { role: "assistant", question }, { role: "assistant", question: later }]; expect(pendingAgentQuestion(messages)?.question).toBe("确认开始吗?"); }); diff --git a/web/test/create-library-button.test.ts b/web/test/create-library-button.test.ts index 86796d01b..46a847e18 100644 --- a/web/test/create-library-button.test.ts +++ b/web/test/create-library-button.test.ts @@ -69,7 +69,7 @@ describe("creation library button", () => { const source = readCreateWorkspaceSource(); const styles = readFileSync(resolve(import.meta.dir, "../src/styles/globals.css"), "utf8"); - expect(source).toContain("import { Reorder, LayoutGroup, motion, useReducedMotion } from \"motion/react\""); + expect(source).toContain('import { Reorder, LayoutGroup, motion, useReducedMotion } from "motion/react"'); expect(source).toContain("