diff --git a/docs/content/docs/progress/pending-test.mdx b/docs/content/docs/progress/pending-test.mdx index b3895e3c3..e1ce54059 100644 --- a/docs/content/docs/progress/pending-test.mdx +++ b/docs/content/docs/progress/pending-test.mdx @@ -5,6 +5,11 @@ description: 当前项目已实现功能的手工验证清单与未确认边界 # 待测试 +## 工作区 100% 缩放下的界面密度 + +- 已收紧用户工作区侧栏、顶栏和导航行、画布桌面端 Dock、Agent 内边距及默认浮窗尺寸;Agent 旧的手动调整尺寸仍保留,可点标题栏「恢复 Agent 紧凑窗口」自行重置。技能组合标签维持透明底和彩色描边。 +- [ ] 在已登录的真实画布和用户工作区以浏览器 100% 缩放验收明暗主题、侧栏展开/折叠、顶部/底部工具栏、Agent 历史与设置、输入区和标签横向滚动;再检查窄屏与触屏下是否截断或遮挡。当前本地独立浏览器会跳转登录页,未将静态检查视为视觉验收。 + ## 画布资源断链、前端发布兼容与画布热点 - 已实现:统一递归识别持久资源字段(含嵌套 `videoPreview`);保存前和历史快照保存时校验当前资源归属/ready 状态,资源缺失返回带路径和 ID 的结构化 409。显式修复保留坏版本历史但要求新版本完整且 revision CAS 成功。后台 `repair-canvas-resources` 默认只读,仅可清除确认缺失的派生视频预览;主媒体问题报告为 unresolved。 diff --git a/web/src/components/canvas/canvas-cloud-agent-chat-ui.tsx b/web/src/components/canvas/canvas-cloud-agent-chat-ui.tsx index c7b7d67fd..17973c2a0 100644 --- a/web/src/components/canvas/canvas-cloud-agent-chat-ui.tsx +++ b/web/src/components/canvas/canvas-cloud-agent-chat-ui.tsx @@ -4,7 +4,7 @@ import { Tooltip } from "@/components/ui/base/tooltip"; import { useCallback, useEffect, useMemo, useRef, useState, type ClipboardEvent as ReactClipboardEvent, type CSSProperties, type KeyboardEvent as ReactKeyboardEvent, type PointerEvent as ReactPointerEvent, type ReactNode } from "react"; import { motion, useReducedMotion } from "motion/react"; -import { ArrowUp, AtSign, CheckCircle2, ChevronDown, ChevronUp, CircleAlert, CircleDot, Eye, HelpCircle, ImagePlus, ListChecks, LoaderCircle, Pencil, Plus, RotateCcw, Sparkles, Square, X, XCircle } from "lucide-react"; +import { ArrowLeft, ArrowUp, AtSign, Bookmark, CheckCircle2, ChevronDown, ChevronUp, CircleAlert, CircleDot, Clapperboard, Eye, HelpCircle, ImagePlus, Layers3, ListChecks, LoaderCircle, Palette, Pencil, Plus, RotateCcw, Shapes, Share2, ShoppingBag, Sparkles, Square, X, XCircle } from "lucide-react"; import { canvasThemes } from "@/lib/canvas-theme"; import { AIMessageMarkdown } from "@/components/ai/ai-message-markdown"; @@ -595,13 +595,13 @@ export type AgentSceneBucket = { }; /** 场景分类:与 presets.json 的 scene 字段、技能的 tag 字段共用同一套 key。 */ -export const AGENT_SCENE_DEFS: Array<{ key: string; label: string }> = [ - { key: "frequent", label: "我的常用" }, - { key: "drama", label: "短剧故事" }, - { key: "ecommerce", label: "广告电商" }, - { key: "creative", label: "视觉创意" }, - { key: "social", label: "传播社媒" }, - { key: "others", label: "其他" }, +export const AGENT_SCENE_DEFS: Array<{ key: string; label: string; icon: typeof Sparkles }> = [ + { key: "frequent", label: "我的常用", icon: Bookmark }, + { key: "drama", label: "短剧故事", icon: Clapperboard }, + { key: "ecommerce", label: "广告电商", icon: ShoppingBag }, + { key: "creative", label: "视觉创意", icon: Palette }, + { key: "social", label: "传播社媒", icon: Share2 }, + { key: "others", label: "其他", icon: Shapes }, ]; export function AgentSceneCapsules({ buckets, installedIds, theme, disabled = false, onPick, onPickSkill }: { @@ -614,7 +614,7 @@ export function AgentSceneCapsules({ buckets, installedIds, theme, disabled = fa }) { // 始终只占一排:默认显示场景分类,点某个场景后在同一排内就地切换内容。 const [activeKey, setActiveKey] = useState(null); - const capsuleClass = "agent-scene-capsule shrink-0 rounded-lg px-3 py-1.5 text-left text-xs focus-visible:outline focus-visible:outline-2"; + const capsuleClass = "agent-scene-capsule shrink-0"; const stop = { onMouseDown: (event: { stopPropagation(): void }) => event.stopPropagation(), onPointerDown: (event: { stopPropagation(): void }) => event.stopPropagation(), @@ -623,12 +623,12 @@ export function AgentSceneCapsules({ buckets, installedIds, theme, disabled = fa const active = activeKey ? visible.find((bucket) => bucket.key === activeKey) || null : null; if (!visible.length) return null; return ( -
-
- - {active ? active.label : "技能组合推荐"} +
+
+
-
+
{active ? ( <> {active.presets.map((preset) => { const missing = preset.skillIds.filter((id) => !installedIds.has(id)).length; @@ -654,16 +655,16 @@ export function AgentSceneCapsules({ buckets, installedIds, theme, disabled = fa disabled={disabled} title={preset.rationale} className={capsuleClass} + data-scene={active.key} {...stop} onClick={(event) => { event.stopPropagation(); onPick(preset); }} > - {preset.name} - - {missing > 0 ? `${preset.skillIds.length} 个技能 · ${missing} 个待装` : `${preset.skillIds.length} 个技能`} - +
-
选择只对当前会话生效;未装的技能会添加到我的技能库。具体用哪张卡由 Agent 按任务检索。
+

仅本会话生效 · 缺失技能将加入技能库 · Agent 按任务调用

); } diff --git a/web/src/components/canvas/canvas-cloud-agent-panel.tsx b/web/src/components/canvas/canvas-cloud-agent-panel.tsx index a4737fdf7..4982b2008 100644 --- a/web/src/components/canvas/canvas-cloud-agent-panel.tsx +++ b/web/src/components/canvas/canvas-cloud-agent-panel.tsx @@ -1,7 +1,7 @@ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, type CSSProperties, type Dispatch, type SetStateAction } from "react"; import { Button, Dropdown, Input } from "antd"; import { AnimatePresence, motion, useReducedMotion } from "motion/react"; -import { ArrowLeft, Check, ChevronRight, CircleDot, Clock3, Download, History, LoaderCircle, MessageSquarePlus, MoveDiagonal2, Settings2, ShieldCheck, Trash2, Sparkles, X } from "lucide-react"; +import { ArrowLeft, Check, ChevronRight, CircleDot, Clock3, Download, History, LoaderCircle, MessageSquarePlus, MoveDiagonal2, RotateCcw, Settings2, ShieldCheck, Trash2, Sparkles, X } from "lucide-react"; import { saveAs } from "file-saver"; import { buildAgentDebugExport } from "@/lib/canvas/agent-debug-export"; import { markdownPlainText } from "@/lib/markdown-plain-text"; @@ -840,6 +840,7 @@ export function CanvasCloudAgentPanel({ canvasId, domainProjectId, nodeCount, re })().catch((cause) => setMessages((current) => appendAgentError(current, `export-${Date.now()}`, cause, "导出失败"))).finally(() => setExporting(false)); }} onSettings={() => setView("settings")} + onResetLayout={panelLayout.reset} onCollapse={onCollapse} /> {run && connectionStatus !== "connected" ? ( @@ -978,7 +979,7 @@ function AgentLauncher({ theme, statusColor, approvalPending, reducedMotion, onO ); } -function AgentHeader({ theme, hasMessages, statusLabel, statusColor, nodeCount, onNew, onHistory, onSettings, onCollapse, onExport, exporting }: { theme: CanvasTheme; hasMessages: boolean; statusLabel: string; statusColor: string; nodeCount: number; onNew: () => void; onHistory: () => void; onSettings: () => void; onCollapse: () => void; onExport: () => void; exporting: boolean }) { +function AgentHeader({ theme, hasMessages, statusLabel, statusColor, nodeCount, onNew, onHistory, onSettings, onResetLayout, onCollapse, onExport, exporting }: { theme: CanvasTheme; hasMessages: boolean; statusLabel: string; statusColor: string; nodeCount: number; onNew: () => void; onHistory: () => void; onSettings: () => void; onResetLayout: () => void; onCollapse: () => void; onExport: () => void; exporting: boolean }) { const appearance = useAppearanceStore((state) => state.appearance.canvas) || DEFAULT_CANVAS_APPEARANCE; return (
@@ -993,6 +994,7 @@ function AgentHeader({ theme, hasMessages, statusLabel, statusColor, nodeCount,
{appearance.agentName} · 当前画布 {nodeCount} 个节点
+