diff --git a/.gitignore b/.gitignore index 4bb71a1..2101f44 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,7 @@ data/ *.tsbuildinfo .DS_Store .idea -web/dist \ No newline at end of file +web/dist + +**/dist +web/public/plugins \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index a8480fd..fa5e453 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## v0.7.1 - 2026-07-15 + ++ [修复] 修复通过 `crypto.randomUUID` 不可用导致页面白屏报错的问题,改用 nanoid 生成 id。 + ## v0.7.0 - 2026-07-14 + [新增] Agent 对话消息改用 streamdown 流式渲染,提升Markdown 内容展示效果。 diff --git a/VERSION b/VERSION index e7f5d1a..6425bba 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v0.7.0 \ No newline at end of file +v0.7.1 \ No newline at end of file diff --git a/web/src/components/canvas/canvas-local-agent-panel.tsx b/web/src/components/canvas/canvas-local-agent-panel.tsx index 6ec1786..36022d1 100644 --- a/web/src/components/canvas/canvas-local-agent-panel.tsx +++ b/web/src/components/canvas/canvas-local-agent-panel.tsx @@ -5,6 +5,7 @@ import copyToClipboard from "copy-to-clipboard"; import { Copy, FolderOpen, History, KeyRound, Link2, LoaderCircle, PlugZap, Plus, RefreshCw, Square, Terminal, Trash2 } from "lucide-react"; import { canvasThemes } from "@/lib/canvas-theme"; +import { randomId } from "@/lib/utils"; import { useThemeStore } from "@/stores/use-theme-store"; import { useUserStore } from "@/stores/use-user-store"; import { useAgentStore, type AgentAttachment, type AgentChatItem, type AgentEventLog, type AgentPanelTab, type AgentPendingToolCall, type AgentThreadSummary } from "@/stores/use-agent-store"; @@ -54,7 +55,7 @@ export function CanvasLocalAgentPanel({ embedded, headless, autoConnect }: { emb const connectedRef = useRef(false); const errorLoggedRef = useRef(false); const attachmentUrlsRef = useRef(new Set()); - const clientIdRef = useRef(typeof crypto === "undefined" ? `${Date.now()}` : crypto.randomUUID()); + const clientIdRef = useRef(randomId()); const endpoint = useMemo(() => url.trim().replace(/\/$/, ""), [url]); const urlAgentAutoConnect = searchParams.has("agentUrl") && searchParams.has("agentToken"); const loadThreads = useCallback(async () => { @@ -1045,7 +1046,7 @@ function formatThreadTime(value?: number) { } function createId() { - return typeof crypto === "undefined" ? `${Date.now()}-${Math.random()}` : crypto.randomUUID(); + return randomId(); } function clamp(value: number, min: number, max: number) { diff --git a/web/src/lib/utils.ts b/web/src/lib/utils.ts index e6a8be0..cd589fb 100644 --- a/web/src/lib/utils.ts +++ b/web/src/lib/utils.ts @@ -1,6 +1,18 @@ import { clsx, type ClassValue } from "clsx"; import { twMerge } from "tailwind-merge"; +import { nanoid } from "nanoid"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } + +/** + * Generate a unique id. + * + * Avoid `crypto.randomUUID`, which is only exposed in secure contexts (HTTPS or + * localhost) — over plain HTTP it is undefined and throws. `nanoid` works in any + * context. + */ +export function randomId(): string { + return nanoid(); +}