@blade-hq/agent-kit 0.4.13 → 0.4.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{SkillStatusBar-DhEw_C2P.d.ts → SkillStatusBar-DCOlTYcT.d.ts} +2 -2
- package/dist/{blade-client-Brjw8njI.d.ts → blade-client-BEjbedNc.d.ts} +4 -32
- package/dist/{chunk-6RVI56IR.js → chunk-47YVQZQ7.js} +2 -2
- package/dist/{chunk-6UVM6PBD.js → chunk-LKNU4NUC.js} +8 -2
- package/dist/chunk-LKNU4NUC.js.map +1 -0
- package/dist/{chunk-C34J6GD3.js → chunk-RMLZ4ZBY.js} +11 -11
- package/dist/chunk-RMLZ4ZBY.js.map +1 -0
- package/dist/{chunk-UWUDHCVV.js → chunk-ROGNJYST.js} +4 -28
- package/dist/chunk-ROGNJYST.js.map +1 -0
- package/dist/{chunk-AGRVE5NY.js → chunk-WQYDTSSV.js} +2 -2
- package/dist/{chunk-JMNQIZOC.js → chunk-WZT2DOBJ.js} +2 -2
- package/dist/client/index.d.ts +4741 -2109
- package/dist/client/index.js +1 -3
- package/dist/react/api/vibe-coding.d.ts +3 -3
- package/dist/react/api/vibe-coding.js +2 -2
- package/dist/react/assets/file-icons/archive/7z.png +0 -0
- package/dist/react/assets/file-icons/archive/bz2.png +0 -0
- package/dist/react/assets/file-icons/archive/dmg.png +0 -0
- package/dist/react/assets/file-icons/archive/gz.png +0 -0
- package/dist/react/assets/file-icons/archive/iso.png +0 -0
- package/dist/react/assets/file-icons/archive/pkg.png +0 -0
- package/dist/react/assets/file-icons/archive/rar.png +0 -0
- package/dist/react/assets/file-icons/archive/tar.png +0 -0
- package/dist/react/assets/file-icons/archive/tgz.png +0 -0
- package/dist/react/assets/file-icons/archive/xz.png +0 -0
- package/dist/react/assets/file-icons/archive/zip.png +0 -0
- package/dist/react/assets/file-icons/audio/aac.png +0 -0
- package/dist/react/assets/file-icons/audio/aiff.png +0 -0
- package/dist/react/assets/file-icons/audio/flac.png +0 -0
- package/dist/react/assets/file-icons/audio/m4a.png +0 -0
- package/dist/react/assets/file-icons/audio/mid.png +0 -0
- package/dist/react/assets/file-icons/audio/mp3.png +0 -0
- package/dist/react/assets/file-icons/audio/ogg.png +0 -0
- package/dist/react/assets/file-icons/audio/wav.png +0 -0
- package/dist/react/assets/file-icons/code/c.png +0 -0
- package/dist/react/assets/file-icons/code/cpp.png +0 -0
- package/dist/react/assets/file-icons/code/cs.png +0 -0
- package/dist/react/assets/file-icons/code/css.png +0 -0
- package/dist/react/assets/file-icons/code/go.png +0 -0
- package/dist/react/assets/file-icons/code/h.png +0 -0
- package/dist/react/assets/file-icons/code/hpp.png +0 -0
- package/dist/react/assets/file-icons/code/html.png +0 -0
- package/dist/react/assets/file-icons/code/java.png +0 -0
- package/dist/react/assets/file-icons/code/js.png +0 -0
- package/dist/react/assets/file-icons/code/json.png +0 -0
- package/dist/react/assets/file-icons/code/jsx.png +0 -0
- package/dist/react/assets/file-icons/code/kt.png +0 -0
- package/dist/react/assets/file-icons/code/lock.png +0 -0
- package/dist/react/assets/file-icons/code/php.png +0 -0
- package/dist/react/assets/file-icons/code/py.png +0 -0
- package/dist/react/assets/file-icons/code/rb.png +0 -0
- package/dist/react/assets/file-icons/code/rs.png +0 -0
- package/dist/react/assets/file-icons/code/scss.png +0 -0
- package/dist/react/assets/file-icons/code/sh.png +0 -0
- package/dist/react/assets/file-icons/code/sql.png +0 -0
- package/dist/react/assets/file-icons/code/svelte.png +0 -0
- package/dist/react/assets/file-icons/code/swift.png +0 -0
- package/dist/react/assets/file-icons/code/toml.png +0 -0
- package/dist/react/assets/file-icons/code/ts.png +0 -0
- package/dist/react/assets/file-icons/code/tsx.png +0 -0
- package/dist/react/assets/file-icons/code/vue.png +0 -0
- package/dist/react/assets/file-icons/code/xml.png +0 -0
- package/dist/react/assets/file-icons/code/yaml.png +0 -0
- package/dist/react/assets/file-icons/code/yml.png +0 -0
- package/dist/react/assets/file-icons/code/zsh.png +0 -0
- package/dist/react/assets/file-icons/config/conf.png +0 -0
- package/dist/react/assets/file-icons/config/env.png +0 -0
- package/dist/react/assets/file-icons/config/ini.png +0 -0
- package/dist/react/assets/file-icons/data/db.png +0 -0
- package/dist/react/assets/file-icons/data/jsonl.png +0 -0
- package/dist/react/assets/file-icons/data/ndjson.png +0 -0
- package/dist/react/assets/file-icons/data/parquet.png +0 -0
- package/dist/react/assets/file-icons/data/plist.png +0 -0
- package/dist/react/assets/file-icons/data/sqlite.png +0 -0
- package/dist/react/assets/file-icons/design/blend.png +0 -0
- package/dist/react/assets/file-icons/design/fig.png +0 -0
- package/dist/react/assets/file-icons/design/sketch.png +0 -0
- package/dist/react/assets/file-icons/design/xd.png +0 -0
- package/dist/react/assets/file-icons/document/epub.png +0 -0
- package/dist/react/assets/file-icons/document/key.png +0 -0
- package/dist/react/assets/file-icons/document/log.png +0 -0
- package/dist/react/assets/file-icons/document/markdown.png +0 -0
- package/dist/react/assets/file-icons/document/md.png +0 -0
- package/dist/react/assets/file-icons/document/numbers.png +0 -0
- package/dist/react/assets/file-icons/document/pages.png +0 -0
- package/dist/react/assets/file-icons/document/pdf.png +0 -0
- package/dist/react/assets/file-icons/document/tex.png +0 -0
- package/dist/react/assets/file-icons/document/txt.png +0 -0
- package/dist/react/assets/file-icons/folder.png +0 -0
- package/dist/react/assets/file-icons/font/otf.png +0 -0
- package/dist/react/assets/file-icons/font/ttf.png +0 -0
- package/dist/react/assets/file-icons/font/woff.png +0 -0
- package/dist/react/assets/file-icons/font/woff2.png +0 -0
- package/dist/react/assets/file-icons/generic-file.png +0 -0
- package/dist/react/assets/file-icons/image/ai.png +0 -0
- package/dist/react/assets/file-icons/image/avif.png +0 -0
- package/dist/react/assets/file-icons/image/bmp.png +0 -0
- package/dist/react/assets/file-icons/image/gif.png +0 -0
- package/dist/react/assets/file-icons/image/heic.png +0 -0
- package/dist/react/assets/file-icons/image/heif.png +0 -0
- package/dist/react/assets/file-icons/image/ico.png +0 -0
- package/dist/react/assets/file-icons/image/jpeg.png +0 -0
- package/dist/react/assets/file-icons/image/jpg.png +0 -0
- package/dist/react/assets/file-icons/image/png.png +0 -0
- package/dist/react/assets/file-icons/image/psd.png +0 -0
- package/dist/react/assets/file-icons/image/svg.png +0 -0
- package/dist/react/assets/file-icons/image/tif.png +0 -0
- package/dist/react/assets/file-icons/image/tiff.png +0 -0
- package/dist/react/assets/file-icons/image/webp.png +0 -0
- package/dist/react/assets/file-icons/office/csv.png +0 -0
- package/dist/react/assets/file-icons/office/doc.png +0 -0
- package/dist/react/assets/file-icons/office/docx.png +0 -0
- package/dist/react/assets/file-icons/office/ppt.png +0 -0
- package/dist/react/assets/file-icons/office/pptx.png +0 -0
- package/dist/react/assets/file-icons/office/rtf.png +0 -0
- package/dist/react/assets/file-icons/office/tsv.png +0 -0
- package/dist/react/assets/file-icons/office/xls.png +0 -0
- package/dist/react/assets/file-icons/office/xlsx.png +0 -0
- package/dist/react/assets/file-icons/open-document/odg.png +0 -0
- package/dist/react/assets/file-icons/open-document/odp.png +0 -0
- package/dist/react/assets/file-icons/open-document/ods.png +0 -0
- package/dist/react/assets/file-icons/open-document/odt.png +0 -0
- package/dist/react/assets/file-icons/video/avi.png +0 -0
- package/dist/react/assets/file-icons/video/flv.png +0 -0
- package/dist/react/assets/file-icons/video/m4v.png +0 -0
- package/dist/react/assets/file-icons/video/mkv.png +0 -0
- package/dist/react/assets/file-icons/video/mov.png +0 -0
- package/dist/react/assets/file-icons/video/mp4.png +0 -0
- package/dist/react/assets/file-icons/video/webm.png +0 -0
- package/dist/react/assets/file-icons/video/wmv.png +0 -0
- package/dist/react/components/chat/index.d.ts +4 -4
- package/dist/react/components/chat/index.js +5 -5
- package/dist/react/components/plan/index.js +3 -3
- package/dist/react/components/session/index.d.ts +1 -1
- package/dist/react/components/session/index.js +3 -3
- package/dist/react/components/workspace/index.js +124 -121
- package/dist/react/components/workspace/index.js.map +1 -1
- package/dist/react/index.d.ts +532 -9
- package/dist/react/index.js +390 -13
- package/dist/react/index.js.map +1 -1
- package/dist/{session-C7m4f0Gl.d.ts → session-nZdIuWrS.d.ts} +2 -0
- package/package.json +1 -2
- package/dist/chunk-6UVM6PBD.js.map +0 -1
- package/dist/chunk-ACHKHQEO.js +0 -29
- package/dist/chunk-ACHKHQEO.js.map +0 -1
- package/dist/chunk-C34J6GD3.js.map +0 -1
- package/dist/chunk-UWUDHCVV.js.map +0 -1
- package/dist/licenses-DZzDCfd0.d.ts +0 -16
- package/dist/react/api/licenses.d.ts +0 -7
- package/dist/react/api/licenses.js +0 -18
- package/dist/react/api/licenses.js.map +0 -1
- /package/dist/{chunk-6RVI56IR.js.map → chunk-47YVQZQ7.js.map} +0 -0
- /package/dist/{chunk-AGRVE5NY.js.map → chunk-WQYDTSSV.js.map} +0 -0
- /package/dist/{chunk-JMNQIZOC.js.map → chunk-WZT2DOBJ.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/react/components/workspace/WorkspaceFilesPanel.tsx","../../../../src/react/components/workspace/FileTree.tsx","../../../../src/react/lib/open-session-file.ts","../../../../src/react/components/ai-elements/file-tree.tsx"],"sourcesContent":["import { useQueryClient } from \"@tanstack/react-query\"\nimport { FileText, FolderTree, FolderUp, Loader2, PanelRightOpen, RefreshCw, Upload } from \"lucide-react\"\nimport { type ChangeEvent, type ReactNode, useEffect, useMemo, useRef, useState } from \"react\"\nimport { uploadFiles } from \"../../api/sessions\"\nimport { isUiMeta } from \"../../lib/ui-meta\"\nimport { cn } from \"../../lib/utils\"\nimport type { PreviewTarget } from \"../../stores/ui-store\"\nimport { useChatStore } from \"../../stores/chat-store\"\nimport { useUiStore } from \"../../stores/ui-store\"\nimport { FileTree } from \"./FileTree\"\n\ninterface WorkspaceFilesPanelProps {\n sessionId: string | null\n enableEditor?: boolean\n className?: string\n treeContainerClassName?: string\n title?: string\n rootPath?: string\n readOnly?: boolean\n onShareFile?: (path: string, name: string) => Promise<void>\n onSync?: () => Promise<void>\n allowDelete?: boolean\n /** Optional slot above the file tree (e.g. phase progress in host app). */\n topSlot?: ReactNode\n /** Custom file open handler; used when enableEditor is false if provided. */\n onOpenFile?: (path: string, name: string) => Promise<void>\n}\n\ntype WorkspaceTab = \"files\" | \"resources\"\n\ninterface InlineResourceItem {\n key: string\n title: string\n target: PreviewTarget\n}\n\nconst EMPTY_MESSAGES: ReturnType<typeof useChatStore.getState>[\"messages\"][string] = []\n\nexport function WorkspaceFilesPanel({\n sessionId,\n enableEditor = false,\n className,\n treeContainerClassName,\n title = \"工作区\",\n rootPath = \".\",\n readOnly = false,\n onShareFile,\n onSync,\n allowDelete = false,\n topSlot,\n onOpenFile,\n}: WorkspaceFilesPanelProps) {\n const [expandedDirs, setExpandedDirs] = useState<Set<string>>(new Set())\n const [isUploading, setIsUploading] = useState(false)\n const [activeTab, setActiveTab] = useState<WorkspaceTab>(\"files\")\n const [isSyncing, setIsSyncing] = useState(false)\n const queryClient = useQueryClient()\n const fileInputRef = useRef<HTMLInputElement>(null)\n const folderInputRef = useRef<HTMLInputElement>(null)\n const messages = useChatStore((state) =>\n sessionId ? (state.messages[sessionId] ?? EMPTY_MESSAGES) : EMPTY_MESSAGES,\n )\n const pushArtifact = useUiStore((state) => state.pushArtifact)\n\n const inlineResources = useMemo<InlineResourceItem[]>(() => {\n if (!sessionId) return []\n return messages.flatMap((message, messageIndex) =>\n (message.blocks ?? []).flatMap((block, blockIndex): InlineResourceItem[] => {\n if (block.type !== \"tool_ui\" || !isUiMeta(block.content) || block.content.target !== \"inline\") {\n return []\n }\n\n const ui = block.content\n const type = ui.resourceHTML ? \"resource-html\" : \"resource-uri\"\n const content = ui.resourceHTML ?? ui.resourceUri ?? ui.resourceURI ?? \"\"\n if (!content) return []\n\n const title =\n ui.title ??\n (typeof block.display_name === \"string\" && block.display_name.trim().length > 0\n ? block.display_name\n : \"可视化产物\")\n const key = `${message.entry_id ?? message.timestamp ?? messageIndex}-${block.tool_call_id ?? \"ui\"}-${blockIndex}`\n\n return [\n {\n key,\n title,\n target: {\n type,\n content,\n title,\n key,\n bridgeSessionId: sessionId,\n },\n },\n ]\n }),\n )\n }, [messages, sessionId])\n\n useEffect(() => {\n if (activeTab === \"resources\" && inlineResources.length === 0) {\n setActiveTab(\"files\")\n }\n }, [activeTab, inlineResources.length])\n\n const uploadTargetDir = () => {\n const candidates = Array.from(expandedDirs)\n .filter((path) => path !== \".\")\n .filter((path) => {\n const parts = path.split(\"/\").filter(Boolean)\n for (let index = 1; index < parts.length; index += 1) {\n const ancestor = parts.slice(0, index).join(\"/\")\n if (!expandedDirs.has(ancestor)) return false\n }\n return true\n })\n\n if (candidates.length === 0) {\n return \".\"\n }\n\n return candidates.reduce((deepestPath, currentPath) => {\n const deepestDepth = deepestPath.split(\"/\").filter(Boolean).length\n const currentDepth = currentPath.split(\"/\").filter(Boolean).length\n return currentDepth > deepestDepth ? currentPath : deepestPath\n }, candidates[0] ?? \".\")\n }\n\n const handleUploadChange = async (event: ChangeEvent<HTMLInputElement>) => {\n const files = event.target.files\n if (!sessionId || !files || files.length === 0) {\n event.target.value = \"\"\n return\n }\n\n setIsUploading(true)\n try {\n const targetDir = uploadTargetDir()\n const result = await uploadFiles(sessionId, targetDir, files)\n await queryClient.invalidateQueries({\n queryKey: [\"file-tree\", sessionId],\n refetchType: \"all\",\n })\n await queryClient.refetchQueries({\n queryKey: [\"file-tree\", sessionId],\n type: \"active\",\n })\n\n if (targetDir !== \".\") {\n setExpandedDirs((prev) => {\n const next = new Set(prev)\n next.add(targetDir)\n return next\n })\n }\n\n if (result.failed.length > 0) {\n alert(`部分文件上传失败: ${result.failed.join(\", \")}`)\n }\n } catch (error) {\n console.error(\"Upload files failed\", error)\n alert(\"上传文件失败\")\n } finally {\n setIsUploading(false)\n event.target.value = \"\"\n }\n }\n\n const handleUploadClick = () => {\n fileInputRef.current?.click()\n }\n\n const handleFolderUploadClick = () => {\n folderInputRef.current?.click()\n }\n\n return (\n <div className={cn(\"flex flex-col\", className)}>\n {topSlot ? <div className=\"mb-3\">{topSlot}</div> : null}\n <div className=\"mb-2 flex shrink-0 items-center justify-between gap-2\">\n <div className=\"flex min-w-0 items-center gap-1 rounded-lg bg-[hsl(var(--muted))]/60 p-0.5 text-[11px] font-medium\">\n <button\n type=\"button\"\n onClick={() => setActiveTab(\"files\")}\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-md px-2 py-1 transition-colors\",\n activeTab === \"files\"\n ? \"bg-[hsl(var(--background))] text-[hsl(var(--foreground))] shadow-sm\"\n : \"text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]\",\n )}\n >\n <FolderTree size={12} />\n {title}\n </button>\n {inlineResources.length > 0 ? (\n <button\n type=\"button\"\n onClick={() => setActiveTab(\"resources\")}\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-md px-2 py-1 transition-colors\",\n activeTab === \"resources\"\n ? \"bg-[hsl(var(--background))] text-[hsl(var(--foreground))] shadow-sm\"\n : \"text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]\",\n )}\n >\n <PanelRightOpen size={12} />\n 可视化产物\n <span className=\"font-mono text-[10px] text-[hsl(var(--muted-foreground))]\">\n {inlineResources.length}\n </span>\n </button>\n ) : null}\n </div>\n {onSync ? <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n disabled={!sessionId || isSyncing}\n onClick={async () => {\n setIsSyncing(true)\n try {\n await onSync()\n await queryClient.invalidateQueries({\n queryKey: [\"file-tree\", sessionId],\n refetchType: \"all\",\n })\n } finally {\n setIsSyncing(false)\n }\n }}\n className=\"rounded p-1 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--muted-foreground))/10] hover:text-[hsl(var(--foreground))] disabled:cursor-not-allowed disabled:opacity-50\"\n title=\"同步共享区\"\n >\n {isSyncing ? <Loader2 size={12} className=\"animate-spin\" /> : <RefreshCw size={12} />}\n </button>\n </div> : null}\n {!readOnly && activeTab === \"files\" ? <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n disabled={!sessionId || isUploading}\n onClick={handleUploadClick}\n className=\"rounded p-1 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--muted-foreground))/10] hover:text-[hsl(var(--foreground))] disabled:cursor-not-allowed disabled:opacity-50\"\n title=\"上传文件\"\n >\n {isUploading ? <Loader2 size={12} className=\"animate-spin\" /> : <Upload size={12} />}\n </button>\n <button\n type=\"button\"\n disabled={!sessionId || isUploading}\n onClick={handleFolderUploadClick}\n className=\"rounded p-1 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--muted-foreground))/10] hover:text-[hsl(var(--foreground))] disabled:cursor-not-allowed disabled:opacity-50\"\n title=\"上传文件夹\"\n >\n {isUploading ? <Loader2 size={12} className=\"animate-spin\" /> : <FolderUp size={12} />}\n </button>\n </div> : null}\n </div>\n {activeTab === \"resources\" && inlineResources.length > 0 ? (\n <div className={cn(\"min-h-0 overflow-auto\", treeContainerClassName)}>\n <div className=\"flex flex-col gap-1.5\">\n {inlineResources.map((item, index) => (\n <button\n key={item.key}\n type=\"button\"\n onClick={() => pushArtifact(item.target)}\n className=\"group flex min-w-0 items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors hover:bg-[hsl(var(--muted))]\"\n title={item.title}\n >\n <FileText size={14} className=\"shrink-0 text-[hsl(var(--primary))]\" />\n <span className=\"min-w-0 flex-1 truncate text-[hsl(var(--foreground))]\">\n {item.title}\n </span>\n <span className=\"shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]\">\n {index + 1}\n </span>\n </button>\n ))}\n </div>\n </div>\n ) : (\n <div className={treeContainerClassName}>\n <FileTree\n key={sessionId ?? \"workspace-empty\"}\n sessionId={sessionId}\n enableEditor={enableEditor}\n onExpandedDirsChange={setExpandedDirs}\n rootPath={rootPath}\n readOnly={readOnly}\n onShareFile={onShareFile}\n allowDelete={allowDelete}\n onOpenFile={onOpenFile}\n />\n </div>\n )}\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple\n className=\"hidden\"\n onChange={handleUploadChange}\n />\n <input\n ref={folderInputRef}\n type=\"file\"\n multiple\n className=\"hidden\"\n onChange={handleUploadChange}\n // biome-ignore lint/suspicious/noExplicitAny: webkitdirectory is a non-standard HTML attribute\n {...({ webkitdirectory: \"\" } as any)}\n />\n </div>\n )\n}\n","import { useQuery, useQueryClient } from \"@tanstack/react-query\"\nimport {\n ChevronRight,\n Copy,\n Download,\n Link2,\n Loader2,\n Pencil,\n Trash2,\n} from \"lucide-react\"\nimport type { ReactNode } from \"react\"\nimport { useEffect, useEffectEvent, useRef, useState } from \"react\"\nimport * as sessionsApi from \"../../api/sessions\"\nimport { apiFetchText } from \"../../api/client\"\nimport { getAuthedUrl } from \"../../api/client\"\nimport { openSessionFileInPreview } from \"../../lib/open-session-file\"\nimport { cn } from \"../../lib/utils\"\nimport { useChatStore } from \"../../stores/chat-store\"\nimport { useSessionStore } from \"../../stores/session-store\"\nimport { useUiStore } from \"../../stores/ui-store\"\nimport { FileTree as AIFileTree, FileTreeActions, FileTreeIcon, FileTreeName } from \"../ai-elements/file-tree\"\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"../ui/collapsible\"\n\ntype FileEntry = Awaited<ReturnType<typeof sessionsApi.listDir>>[number]\n\nconst ROOT_PATH = \".\"\nconst TREE_ROW_CLASS =\n \"group flex w-full items-center gap-1 rounded px-2 py-1 text-left transition-colors hover:bg-muted/50\"\nconst FILE_ICON_GROUPS: Record<string, string> = {\n csv: \"office\",\n doc: \"office\",\n docx: \"office\",\n ppt: \"office\",\n pptx: \"office\",\n rtf: \"office\",\n tsv: \"office\",\n xls: \"office\",\n xlsx: \"office\",\n odg: \"open-document\",\n odp: \"open-document\",\n ods: \"open-document\",\n odt: \"open-document\",\n epub: \"document\",\n key: \"document\",\n log: \"document\",\n markdown: \"document\",\n md: \"document\",\n numbers: \"document\",\n pages: \"document\",\n pdf: \"document\",\n tex: \"document\",\n txt: \"document\",\n ai: \"image\",\n avif: \"image\",\n bmp: \"image\",\n gif: \"image\",\n heic: \"image\",\n heif: \"image\",\n ico: \"image\",\n jpeg: \"image\",\n jpg: \"image\",\n png: \"image\",\n psd: \"image\",\n svg: \"image\",\n tif: \"image\",\n tiff: \"image\",\n webp: \"image\",\n avi: \"video\",\n flv: \"video\",\n m4v: \"video\",\n mkv: \"video\",\n mov: \"video\",\n mp4: \"video\",\n webm: \"video\",\n wmv: \"video\",\n aac: \"audio\",\n aiff: \"audio\",\n flac: \"audio\",\n m4a: \"audio\",\n mid: \"audio\",\n mp3: \"audio\",\n ogg: \"audio\",\n wav: \"audio\",\n \"7z\": \"archive\",\n bz2: \"archive\",\n dmg: \"archive\",\n gz: \"archive\",\n iso: \"archive\",\n pkg: \"archive\",\n rar: \"archive\",\n tar: \"archive\",\n tgz: \"archive\",\n xz: \"archive\",\n zip: \"archive\",\n c: \"code\",\n cpp: \"code\",\n cs: \"code\",\n css: \"code\",\n go: \"code\",\n h: \"code\",\n hpp: \"code\",\n html: \"code\",\n java: \"code\",\n js: \"code\",\n json: \"code\",\n jsx: \"code\",\n kt: \"code\",\n lock: \"code\",\n php: \"code\",\n py: \"code\",\n rb: \"code\",\n rs: \"code\",\n scss: \"code\",\n sh: \"code\",\n sql: \"code\",\n svelte: \"code\",\n swift: \"code\",\n toml: \"code\",\n ts: \"code\",\n tsx: \"code\",\n vue: \"code\",\n xml: \"code\",\n yaml: \"code\",\n yml: \"code\",\n zsh: \"code\",\n db: \"data\",\n jsonl: \"data\",\n ndjson: \"data\",\n parquet: \"data\",\n plist: \"data\",\n sqlite: \"data\",\n otf: \"font\",\n ttf: \"font\",\n woff: \"font\",\n woff2: \"font\",\n blend: \"design\",\n fig: \"design\",\n sketch: \"design\",\n xd: \"design\",\n conf: \"config\",\n env: \"config\",\n ini: \"config\",\n}\n\ninterface FileTreeProps {\n sessionId: string | null\n checkActiveSession?: boolean\n enableEditor?: boolean\n onExpandedDirsChange?: (dirs: Set<string>) => void\n rootPath?: string\n readOnly?: boolean\n onShareFile?: (path: string, name: string) => Promise<void>\n allowDelete?: boolean\n onOpenFile?: (path: string, name: string) => Promise<void>\n}\n\nexport function FileTree({\n sessionId,\n checkActiveSession = true,\n enableEditor = false,\n onExpandedDirsChange,\n rootPath = ROOT_PATH,\n readOnly = false,\n onShareFile,\n allowDelete = false,\n onOpenFile,\n}: FileTreeProps) {\n const pushArtifact = useUiStore((state) => state.pushArtifact)\n const [expandedDirs, setExpandedDirs] = useState<Set<string>>(new Set([rootPath]))\n const [selectedPath, setSelectedPath] = useState<string | undefined>()\n const [openingFilePath, setOpeningFilePath] = useState<string | null>(null)\n const isStreaming = useChatStore((s) => (sessionId ? (s.isStreaming[sessionId] ?? false) : false))\n const queryClient = useQueryClient()\n const prevStreamingRef = useRef(isStreaming)\n\n const applyExpandedDirs = useEffectEvent((dirs: Set<string>) => {\n setExpandedDirs(dirs)\n onExpandedDirsChange?.(dirs)\n })\n\n useEffect(() => {\n if (prevStreamingRef.current && !isStreaming && sessionId) {\n queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n }\n prevStreamingRef.current = isStreaming\n }, [isStreaming, sessionId, queryClient])\n\n const onExpandedDirsChangeStable = useEffectEvent((dirs: Set<string>) => {\n onExpandedDirsChange?.(dirs)\n })\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: mount-only effect, intentionally empty deps\n useEffect(() => {\n onExpandedDirsChangeStable(expandedDirs)\n }, [])\n\n const handleExpandedChange = (dirs: Set<string>) => {\n applyExpandedDirs(dirs)\n }\n\n const toggleExpandedDir = (path: string) => {\n const next = new Set(expandedDirs)\n if (next.has(path)) {\n next.delete(path)\n } else {\n next.add(path)\n }\n handleExpandedChange(next)\n }\n\n const handleTreePathChange = useEffectEvent((previousPath: string, nextPath?: string) => {\n setSelectedPath((current) => {\n if (!current) {\n return current\n }\n if (current === previousPath || current.startsWith(`${previousPath}/`)) {\n if (!nextPath) {\n return undefined\n }\n return current === previousPath\n ? nextPath\n : `${nextPath}${current.slice(previousPath.length)}`\n }\n return current\n })\n\n const nextExpanded = new Set<string>()\n for (const path of expandedDirs) {\n if (path === previousPath || path.startsWith(`${previousPath}/`)) {\n if (nextPath) {\n nextExpanded.add(\n path === previousPath ? nextPath : `${nextPath}${path.slice(previousPath.length)}`,\n )\n }\n continue\n }\n nextExpanded.add(path)\n }\n handleExpandedChange(nextExpanded)\n })\n\n const {\n data: rootEntries,\n isLoading: rootLoading,\n error: rootError,\n } = useQuery({\n queryKey: [\"file-tree\", sessionId, rootPath],\n queryFn: () => sessionsApi.listDir(sessionId!, rootPath),\n enabled: !!sessionId,\n refetchInterval: isStreaming ? 60_000 : false,\n })\n\n const handleOpenFile = useEffectEvent(async (path: string, name: string) => {\n if (!sessionId) return\n const currentSessionId = sessionId\n setOpeningFilePath(path)\n setSelectedPath(path)\n try {\n if (onOpenFile) {\n await onOpenFile(path, name)\n } else if (enableEditor) {\n const content = await apiFetchText(\n `/api/sessions/${encodeURIComponent(sessionId)}/files/${encodeURIComponent(path)}`,\n )\n void content\n alert(\"enableEditor 需在宿主应用中提供 onOpenFile\")\n } else {\n await openSessionFileInPreview(sessionId, path, name, pushArtifact, () => {\n return checkActiveSession ? useSessionStore.getState().activeSessionId === currentSessionId : true\n })\n }\n } finally {\n setOpeningFilePath((current) => (current === path ? null : current))\n }\n })\n\n const handleSelect = (path: string) => {\n setSelectedPath(path)\n }\n\n if (!sessionId) {\n return <EmptyState title=\"暂无活跃会话\" description=\"选择或创建会话后查看工作区文件\" />\n }\n\n if (rootLoading) {\n return (\n <div className=\"flex items-center gap-2 px-3 py-4 text-sm text-[hsl(var(--muted-foreground))]\">\n <Loader2 size={14} className=\"animate-spin\" />\n <span>加载中...</span>\n </div>\n )\n }\n\n if (rootError) {\n return (\n <EmptyState\n title=\"文件树加载失败\"\n description={rootError instanceof Error ? rootError.message : \"加载失败\"}\n />\n )\n }\n\n if (!rootEntries || rootEntries.length === 0) {\n return <EmptyState title=\"当前工作区为空\" description=\"会话产生文件后会显示在这里\" />\n }\n\n return (\n <AIFileTree\n expanded={expandedDirs}\n onExpandedChange={handleExpandedChange}\n selectedPath={selectedPath}\n onSelect={handleSelect}\n className=\"border-none bg-transparent\"\n >\n {rootEntries.map((entry) =>\n entry.is_dir ? (\n <FolderNode\n key={entry.path}\n entry={entry}\n expandedDirs={expandedDirs}\n isStreaming={isStreaming}\n onOpenFile={handleOpenFile}\n onSelectPath={handleSelect}\n onToggleDir={toggleExpandedDir}\n onTreePathChange={handleTreePathChange}\n openingFilePath={openingFilePath}\n selectedPath={selectedPath}\n sessionId={sessionId}\n readOnly={readOnly}\n onShareFile={onShareFile}\n allowDelete={allowDelete}\n />\n ) : (\n <FileNode\n key={entry.path}\n entry={entry}\n onOpenFile={handleOpenFile}\n onSelectPath={handleSelect}\n onTreePathChange={handleTreePathChange}\n openingFilePath={openingFilePath}\n selectedPath={selectedPath}\n sessionId={sessionId}\n readOnly={readOnly}\n onShareFile={onShareFile}\n allowDelete={allowDelete}\n />\n ),\n )}\n </AIFileTree>\n )\n}\n\nfunction FolderNode({\n entry,\n expandedDirs,\n isStreaming,\n openingFilePath,\n onOpenFile,\n onSelectPath,\n onToggleDir,\n onTreePathChange,\n selectedPath,\n sessionId,\n readOnly,\n onShareFile,\n allowDelete,\n}: {\n entry: FileEntry\n expandedDirs: Set<string>\n isStreaming: boolean\n openingFilePath: string | null\n onOpenFile: (path: string, name: string) => Promise<void>\n onSelectPath: (path: string) => void\n onToggleDir: (path: string) => void\n onTreePathChange: (previousPath: string, nextPath?: string) => void\n selectedPath?: string\n sessionId: string\n readOnly: boolean\n onShareFile?: (path: string, name: string) => Promise<void>\n allowDelete: boolean\n}) {\n const queryClient = useQueryClient()\n const isExpanded = expandedDirs.has(entry.path)\n const isSelected = selectedPath === entry.path\n const renameInputRef = useRef<HTMLInputElement>(null)\n const [isRenaming, setIsRenaming] = useState(false)\n const [renamingValue, setRenamingValue] = useState(entry.name)\n const [activeAction, setActiveAction] = useState<\"copy\" | \"delete\" | \"rename\" | \"share\" | null>(null)\n\n const downloadUrl = sessionsApi.getDownloadDirUrl(sessionId, entry.path)\n\n useEffect(() => {\n if (!isRenaming) setRenamingValue(entry.name)\n }, [entry.name, isRenaming])\n\n useEffect(() => {\n if (!isRenaming) return\n renameInputRef.current?.focus()\n renameInputRef.current?.select()\n }, [isRenaming])\n\n const finishRename = useEffectEvent(async () => {\n const nextName = renamingValue.trim()\n if (!nextName || nextName === entry.name) {\n setIsRenaming(false)\n setRenamingValue(entry.name)\n return\n }\n setActiveAction(\"rename\")\n try {\n const result = await sessionsApi.renameFile(sessionId, entry.path, nextName)\n onTreePathChange(entry.path, result.path)\n setIsRenaming(false)\n await queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n } catch (error) {\n alert(getErrorMessage(error, \"重命名失败\"))\n renameInputRef.current?.focus()\n renameInputRef.current?.select()\n } finally {\n setActiveAction(null)\n }\n })\n\n const cancelRename = () => {\n setIsRenaming(false)\n setRenamingValue(entry.name)\n }\n\n const handleCopy = async () => {\n setActiveAction(\"copy\")\n try {\n await sessionsApi.copyFile(sessionId, entry.path)\n await queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n } catch (error) {\n alert(getErrorMessage(error, \"复制目录失败\"))\n } finally {\n setActiveAction(null)\n }\n }\n\n const handleDelete = async () => {\n if (!window.confirm(`确认删除目录\"${entry.name}\"吗?`)) {\n return\n }\n setActiveAction(\"delete\")\n try {\n await sessionsApi.deleteFile(sessionId, entry.path)\n onTreePathChange(entry.path)\n await queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n } catch (error) {\n alert(getErrorMessage(error, \"删除目录失败\"))\n } finally {\n setActiveAction(null)\n }\n }\n\n return (\n <Collapsible open={isExpanded} onOpenChange={() => onToggleDir(entry.path)}>\n <div>\n <div className={cn(TREE_ROW_CLASS, isSelected && \"bg-muted\")}>\n <CollapsibleTrigger asChild>\n <button\n type=\"button\"\n className=\"flex shrink-0 cursor-pointer items-center rounded border-none bg-transparent p-0\"\n title={isExpanded ? \"收起目录\" : \"展开目录\"}\n >\n <ChevronRight\n className={cn(\n \"size-4 shrink-0 text-[hsl(var(--muted-foreground))] transition-transform\",\n isExpanded && \"rotate-90\",\n )}\n />\n </button>\n </CollapsibleTrigger>\n {isRenaming ? (\n <>\n <FileTreeIcon>{getFolderIcon()}</FileTreeIcon>\n <input\n ref={renameInputRef}\n value={renamingValue}\n className=\"h-6 min-w-0 flex-1 rounded border border-[hsl(var(--border))] bg-background px-2 text-xs outline-none ring-offset-background focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))]\"\n disabled={activeAction === \"rename\"}\n onBlur={() => void finishRename()}\n onChange={(event) => setRenamingValue(event.target.value)}\n onClick={(event) => event.stopPropagation()}\n onKeyDown={(event) => {\n event.stopPropagation()\n if (event.key === \"Enter\") {\n event.preventDefault()\n void finishRename()\n } else if (event.key === \"Escape\") {\n event.preventDefault()\n cancelRename()\n }\n }}\n />\n </>\n ) : (\n <button\n type=\"button\"\n className=\"flex min-w-0 flex-1 cursor-pointer items-center gap-1 border-none bg-transparent p-0 text-left\"\n onClick={() => {\n onToggleDir(entry.path)\n onSelectPath(entry.path)\n }}\n >\n <FileTreeIcon>{getFolderIcon()}</FileTreeIcon>\n <FileTreeName className=\"min-w-0 flex-1\">{entry.name}</FileTreeName>\n </button>\n )}\n {!readOnly ? <FileTreeActions className=\"ml-auto hidden shrink-0 group-hover:flex\">\n <TreeActionButton\n onClick={() => {\n const anchor = document.createElement(\"a\")\n anchor.href = downloadUrl\n anchor.download = `${entry.name}.zip`\n anchor.click()\n }}\n title=\"下载目录\"\n >\n <Download size={12} />\n </TreeActionButton>\n <TreeActionButton\n disabled={activeAction !== null}\n onClick={() => {\n onSelectPath(entry.path)\n setRenamingValue(entry.name)\n setIsRenaming(true)\n }}\n title=\"重命名\"\n >\n {activeAction === \"rename\" ? <Loader2 size={12} className=\"animate-spin\" /> : <Pencil size={12} />}\n </TreeActionButton>\n <TreeActionButton\n disabled={activeAction !== null}\n onClick={() => void handleCopy()}\n title=\"复制目录\"\n >\n {activeAction === \"copy\" ? <Loader2 size={12} className=\"animate-spin\" /> : <Copy size={12} />}\n </TreeActionButton>\n <TreeActionButton\n disabled={activeAction !== null || !onShareFile}\n onClick={async () => {\n if (!onShareFile) return\n setActiveAction(\"share\")\n try {\n await onShareFile(entry.path, entry.name)\n await queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n } catch (error) {\n alert(getErrorMessage(error, \"共享失败\"))\n } finally {\n setActiveAction(null)\n }\n }}\n title=\"共享到 .share\"\n >\n {activeAction === \"share\" ? <Loader2 size={12} className=\"animate-spin\" /> : <Link2 size={12} />}\n </TreeActionButton>\n <TreeActionButton\n disabled={activeAction !== null}\n onClick={() => void handleDelete()}\n title=\"删除目录\"\n >\n {activeAction === \"delete\" ? <Loader2 size={12} className=\"animate-spin\" /> : <Trash2 size={12} />}\n </TreeActionButton>\n </FileTreeActions> : allowDelete ? (\n <FileTreeActions className=\"ml-auto hidden shrink-0 group-hover:flex\">\n <TreeActionButton\n disabled={activeAction !== null}\n onClick={() => void handleDelete()}\n title=\"删除目录\"\n >\n {activeAction === \"delete\" ? <Loader2 size={12} className=\"animate-spin\" /> : <Trash2 size={12} />}\n </TreeActionButton>\n </FileTreeActions>\n ) : null}\n </div>\n <CollapsibleContent>\n <div className=\"ml-4 border-l pl-2\">\n <LazyDirChildren\n dirPath={entry.path}\n expandedDirs={expandedDirs}\n isStreaming={isStreaming}\n onOpenFile={onOpenFile}\n onSelectPath={onSelectPath}\n onToggleDir={onToggleDir}\n onTreePathChange={onTreePathChange}\n openingFilePath={openingFilePath}\n selectedPath={selectedPath}\n sessionId={sessionId}\n readOnly={readOnly}\n onShareFile={onShareFile}\n allowDelete={allowDelete}\n />\n </div>\n </CollapsibleContent>\n </div>\n </Collapsible>\n )\n}\n\nfunction FileNode({\n entry,\n onOpenFile,\n onSelectPath,\n onTreePathChange,\n openingFilePath,\n selectedPath,\n sessionId,\n readOnly,\n onShareFile,\n allowDelete,\n}: {\n entry: FileEntry\n onOpenFile: (path: string, name: string) => Promise<void>\n onSelectPath: (path: string) => void\n onTreePathChange: (previousPath: string, nextPath?: string) => void\n openingFilePath: string | null\n selectedPath?: string\n sessionId: string\n readOnly: boolean\n onShareFile?: (path: string, name: string) => Promise<void>\n allowDelete: boolean\n}) {\n const downloadUrl = getAuthedUrl(`/api/sessions/${sessionId}/files/${encodeURIComponent(entry.path)}`)\n const isOpening = openingFilePath === entry.path\n const isSelected = selectedPath === entry.path\n const queryClient = useQueryClient()\n const renameInputRef = useRef<HTMLInputElement>(null)\n const [isRenaming, setIsRenaming] = useState(false)\n const [renamingValue, setRenamingValue] = useState(entry.name)\n const [activeAction, setActiveAction] = useState<\"copy\" | \"delete\" | \"rename\" | \"share\" | null>(null)\n\n useEffect(() => {\n if (!isRenaming) {\n setRenamingValue(entry.name)\n }\n }, [entry.name, isRenaming])\n\n useEffect(() => {\n if (!isRenaming) {\n return\n }\n renameInputRef.current?.focus()\n renameInputRef.current?.select()\n }, [isRenaming])\n\n const finishRename = useEffectEvent(async () => {\n const nextName = renamingValue.trim()\n if (!nextName || nextName === entry.name) {\n setIsRenaming(false)\n setRenamingValue(entry.name)\n return\n }\n\n setActiveAction(\"rename\")\n try {\n const result = await sessionsApi.renameFile(sessionId, entry.path, nextName)\n onTreePathChange(entry.path, result.path)\n setIsRenaming(false)\n await queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n } catch (error) {\n alert(getErrorMessage(error, \"重命名失败\"))\n renameInputRef.current?.focus()\n renameInputRef.current?.select()\n } finally {\n setActiveAction(null)\n }\n })\n\n const cancelRename = () => {\n setIsRenaming(false)\n setRenamingValue(entry.name)\n }\n\n const handleCopy = async () => {\n setActiveAction(\"copy\")\n try {\n await sessionsApi.copyFile(sessionId, entry.path)\n await queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n } catch (error) {\n alert(getErrorMessage(error, \"复制文件失败\"))\n } finally {\n setActiveAction(null)\n }\n }\n\n const handleDelete = async () => {\n if (!window.confirm(`确认删除\"${entry.name}\"吗?`)) {\n return\n }\n setActiveAction(\"delete\")\n try {\n await sessionsApi.deleteFile(sessionId, entry.path)\n onTreePathChange(entry.path)\n await queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n } catch (error) {\n alert(getErrorMessage(error, \"删除文件失败\"))\n } finally {\n setActiveAction(null)\n }\n }\n\n return (\n <div className={cn(TREE_ROW_CLASS, isSelected && \"bg-muted\")}>\n <span className=\"size-4 shrink-0\" />\n <FileTreeIcon>{getFileIcon(entry.name)}</FileTreeIcon>\n {isRenaming ? (\n <input\n ref={renameInputRef}\n value={renamingValue}\n className=\"h-6 min-w-0 flex-1 rounded border border-[hsl(var(--border))] bg-background px-2 text-xs outline-none ring-offset-background focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))]\"\n disabled={activeAction === \"rename\"}\n onBlur={() => void finishRename()}\n onChange={(event) => setRenamingValue(event.target.value)}\n onClick={(event) => event.stopPropagation()}\n onKeyDown={(event) => {\n event.stopPropagation()\n if (event.key === \"Enter\") {\n event.preventDefault()\n void finishRename()\n } else if (event.key === \"Escape\") {\n event.preventDefault()\n cancelRename()\n }\n }}\n />\n ) : (\n <button\n type=\"button\"\n className=\"flex min-w-0 flex-1 cursor-pointer items-center border-none bg-transparent p-0 text-left\"\n onClick={() => {\n onSelectPath(entry.path)\n void onOpenFile(entry.path, entry.name)\n }}\n >\n <FileTreeName className=\"min-w-0 flex-1\">{entry.name}</FileTreeName>\n <FileTagList tags={entry.tags} />\n </button>\n )}\n {isOpening ? (\n <Loader2 size={12} className=\"ml-auto shrink-0 animate-spin text-[hsl(var(--muted-foreground))]\" />\n ) : !readOnly ? (\n <FileTreeActions className=\"ml-auto hidden shrink-0 group-hover:flex\">\n <TreeActionButton\n onClick={() => {\n const anchor = document.createElement(\"a\")\n anchor.href = downloadUrl\n anchor.download = entry.name\n anchor.click()\n }}\n title=\"下载文件\"\n >\n <Download size={12} />\n </TreeActionButton>\n <TreeActionButton\n disabled={activeAction !== null}\n onClick={() => {\n onSelectPath(entry.path)\n setRenamingValue(entry.name)\n setIsRenaming(true)\n }}\n title=\"重命名\"\n >\n {activeAction === \"rename\" ? (\n <Loader2 size={12} className=\"animate-spin\" />\n ) : (\n <Pencil size={12} />\n )}\n </TreeActionButton>\n <TreeActionButton\n disabled={activeAction !== null}\n onClick={() => void handleCopy()}\n title=\"复制文件\"\n >\n {activeAction === \"copy\" ? <Loader2 size={12} className=\"animate-spin\" /> : <Copy size={12} />}\n </TreeActionButton>\n <TreeActionButton\n disabled={activeAction !== null || !onShareFile}\n onClick={async () => {\n if (!onShareFile) return\n setActiveAction(\"share\")\n try {\n await onShareFile(entry.path, entry.name)\n await queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n } catch (error) {\n alert(getErrorMessage(error, \"共享失败\"))\n } finally {\n setActiveAction(null)\n }\n }}\n title=\"共享到 .share\"\n >\n {activeAction === \"share\" ? <Loader2 size={12} className=\"animate-spin\" /> : <Link2 size={12} />}\n </TreeActionButton>\n <TreeActionButton\n disabled={activeAction !== null}\n onClick={() => void handleDelete()}\n title=\"删除文件\"\n >\n {activeAction === \"delete\" ? (\n <Loader2 size={12} className=\"animate-spin\" />\n ) : (\n <Trash2 size={12} />\n )}\n </TreeActionButton>\n </FileTreeActions>\n ) : allowDelete ? (\n <FileTreeActions className=\"ml-auto hidden shrink-0 group-hover:flex\">\n <TreeActionButton\n disabled={activeAction !== null}\n onClick={() => void handleDelete()}\n title=\"删除文件\"\n >\n {activeAction === \"delete\" ? <Loader2 size={12} className=\"animate-spin\" /> : <Trash2 size={12} />}\n </TreeActionButton>\n </FileTreeActions>\n ) : null}\n </div>\n )\n}\n\nfunction LazyDirChildren({\n dirPath,\n expandedDirs,\n isStreaming,\n onOpenFile,\n onSelectPath,\n onToggleDir,\n onTreePathChange,\n openingFilePath,\n selectedPath,\n sessionId,\n readOnly,\n onShareFile,\n allowDelete,\n}: {\n dirPath: string\n expandedDirs: Set<string>\n isStreaming: boolean\n onOpenFile: (path: string, name: string) => Promise<void>\n onSelectPath: (path: string) => void\n onToggleDir: (path: string) => void\n onTreePathChange: (previousPath: string, nextPath?: string) => void\n openingFilePath: string | null\n selectedPath?: string\n sessionId: string\n readOnly: boolean\n onShareFile?: (path: string, name: string) => Promise<void>\n allowDelete: boolean\n}) {\n const {\n data: entries,\n isLoading,\n error,\n } = useQuery({\n queryKey: [\"file-tree\", sessionId, dirPath],\n queryFn: () => sessionsApi.listDir(sessionId, dirPath),\n refetchInterval: isStreaming ? 60_000 : false,\n })\n\n if (isLoading) {\n return (\n <div className=\"flex items-center gap-2 px-2 py-1 text-xs text-[hsl(var(--muted-foreground))]\">\n <Loader2 size={12} className=\"animate-spin\" />\n <span>加载中...</span>\n </div>\n )\n }\n if (error) {\n return (\n <div className=\"px-2 py-1 text-xs text-[hsl(var(--muted-foreground))]\">\n {error instanceof Error ? error.message : \"加载失败\"}\n </div>\n )\n }\n if (!entries || entries.length === 0) {\n return <div className=\"px-2 py-1 text-xs text-[hsl(var(--muted-foreground))]\">空目录</div>\n }\n\n return (\n <>\n {entries.map((child) =>\n child.is_dir ? (\n <FolderNode\n key={child.path}\n entry={child}\n expandedDirs={expandedDirs}\n isStreaming={isStreaming}\n onOpenFile={onOpenFile}\n onSelectPath={onSelectPath}\n onToggleDir={onToggleDir}\n onTreePathChange={onTreePathChange}\n openingFilePath={openingFilePath}\n selectedPath={selectedPath}\n sessionId={sessionId}\n readOnly={readOnly}\n onShareFile={onShareFile}\n allowDelete={allowDelete}\n />\n ) : (\n <FileNode\n key={child.path}\n entry={child}\n onOpenFile={onOpenFile}\n onSelectPath={onSelectPath}\n onTreePathChange={onTreePathChange}\n openingFilePath={openingFilePath}\n selectedPath={selectedPath}\n sessionId={sessionId}\n readOnly={readOnly}\n onShareFile={onShareFile}\n allowDelete={allowDelete}\n />\n ),\n )}\n </>\n )\n}\n\nfunction FileTagList({ tags }: { tags?: string[] }) {\n if (!tags || tags.length === 0) return null\n return (\n <span className=\"ml-2 flex min-w-0 shrink-0 items-center gap-1\">\n {tags.map((tag) => (\n <span\n key={tag}\n className=\"max-w-20 truncate rounded border border-[hsl(var(--border))] bg-[hsl(var(--muted))] px-1.5 py-0.5 text-[10px] leading-none text-[hsl(var(--muted-foreground))]\"\n title={tag}\n >\n {tag}\n </span>\n ))}\n </span>\n )\n}\n\nfunction TreeActionButton({\n children,\n disabled = false,\n onClick,\n title,\n}: {\n children: ReactNode\n disabled?: boolean\n onClick: () => void\n title: string\n}) {\n return (\n <button\n type=\"button\"\n disabled={disabled}\n onClick={onClick}\n title={title}\n className=\"flex items-center rounded p-1 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--muted-foreground))/10] hover:text-[hsl(var(--foreground))] disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {children}\n </button>\n )\n}\n\nfunction EmptyState({ title, description }: { title: string; description: string }) {\n return (\n <div className=\"flex h-full min-h-[12rem] flex-col items-center justify-center gap-3 px-6 text-center\">\n <div className=\"flex h-10 w-10 items-center justify-center text-[hsl(var(--muted-foreground))]\">\n {getFolderIcon()}\n </div>\n <div className=\"space-y-1\">\n <div className=\"text-sm font-medium text-[hsl(var(--foreground))]\">{title}</div>\n <div className=\"text-sm text-[hsl(var(--muted-foreground))]\">{description}</div>\n </div>\n </div>\n )\n}\n\nfunction getFileIcon(fileName: string): ReactNode {\n const ext = fileName.split(\".\").pop()?.toLowerCase() ?? \"\"\n const group = FILE_ICON_GROUPS[ext]\n const src = group ? `/file-icons/${group}/${ext}.png` : \"/file-icons/generic-file.png\"\n return <FileTypeIcon src={src} alt={`${ext || \"file\"} 文件`} />\n}\n\nfunction getFolderIcon(): ReactNode {\n return <FileTypeIcon src=\"/file-icons/folder.png\" alt=\"文件夹\" />\n}\n\nfunction FileTypeIcon({ src, alt }: { src: string; alt: string }) {\n return (\n <img\n src={src}\n alt={alt}\n className=\"size-4 shrink-0 object-contain\"\n draggable={false}\n loading=\"lazy\"\n />\n )\n}\n\nfunction getErrorMessage(error: unknown, fallback: string): string {\n if (error instanceof Error && error.message) {\n return error.message\n }\n return fallback\n}\n","import type { PreviewTarget } from \"../stores/ui-store\"\nimport { resolveSessionFilePreviewTarget } from \"./session-file-preview\"\n\nexport async function openSessionFileInPreview(\n sessionId: string,\n filePath: string,\n fileName: string,\n pushArtifact: (target: PreviewTarget) => void,\n shouldOpen: () => boolean = () => true,\n): Promise<void> {\n try {\n const target = await resolveSessionFilePreviewTarget(sessionId, filePath, fileName)\n if (!shouldOpen()) {\n return\n }\n pushArtifact(target)\n } catch {\n /* file may not exist */\n }\n}\n","\"use client\";\n\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"../ui/collapsible\"\nimport { cn } from \"../../lib/utils\"\nimport {\n ChevronRightIcon,\n FileIcon,\n FolderIcon,\n FolderOpenIcon,\n} from \"lucide-react\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n} from \"react\";\n\ninterface FileTreeContextType {\n expandedPaths: Set<string>;\n togglePath: (path: string) => void;\n selectedPath?: string;\n onSelect?: (path: string) => void;\n}\n\n// Default noop for context default value\n// oxlint-disable-next-line eslint(no-empty-function)\nconst noop = () => {};\n\nconst FileTreeContext = createContext<FileTreeContextType>({\n // oxlint-disable-next-line eslint-plugin-unicorn(no-new-builtin)\n expandedPaths: new Set(),\n togglePath: noop,\n});\n\nexport type FileTreeProps = Omit<HTMLAttributes<HTMLDivElement>, \"onSelect\"> & {\n expanded?: Set<string>;\n defaultExpanded?: Set<string>;\n selectedPath?: string;\n onSelect?: (path: string) => void;\n onExpandedChange?: (expanded: Set<string>) => void;\n};\n\nexport const FileTree = ({\n expanded: controlledExpanded,\n defaultExpanded = new Set(),\n selectedPath,\n onSelect,\n onExpandedChange,\n className,\n children,\n ...props\n}: FileTreeProps) => {\n const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);\n const expandedPaths = controlledExpanded ?? internalExpanded;\n\n const togglePath = useCallback(\n (path: string) => {\n const newExpanded = new Set(expandedPaths);\n if (newExpanded.has(path)) {\n newExpanded.delete(path);\n } else {\n newExpanded.add(path);\n }\n setInternalExpanded(newExpanded);\n onExpandedChange?.(newExpanded);\n },\n [expandedPaths, onExpandedChange]\n );\n\n const contextValue = useMemo(\n () => ({ expandedPaths, onSelect, selectedPath, togglePath }),\n [expandedPaths, onSelect, selectedPath, togglePath]\n );\n\n return (\n <FileTreeContext.Provider value={contextValue}>\n <div\n className={cn(\n \"rounded-lg border bg-background font-mono text-sm\",\n className\n )}\n role=\"tree\"\n {...props}\n >\n <div className=\"p-2\">{children}</div>\n </div>\n </FileTreeContext.Provider>\n );\n};\n\nexport type FileTreeIconProps = HTMLAttributes<HTMLSpanElement>;\n\nexport const FileTreeIcon = ({\n className,\n children,\n ...props\n}: FileTreeIconProps) => (\n <span className={cn(\"shrink-0\", className)} {...props}>\n {children}\n </span>\n);\n\nexport type FileTreeNameProps = HTMLAttributes<HTMLSpanElement>;\n\nexport const FileTreeName = ({\n className,\n children,\n ...props\n}: FileTreeNameProps) => (\n <span className={cn(\"truncate\", className)} {...props}>\n {children}\n </span>\n);\n\ninterface FileTreeFolderContextType {\n path: string;\n name: string;\n isExpanded: boolean;\n}\n\nconst FileTreeFolderContext = createContext<FileTreeFolderContextType>({\n isExpanded: false,\n name: \"\",\n path: \"\",\n});\n\nexport type FileTreeFolderProps = HTMLAttributes<HTMLDivElement> & {\n path: string;\n name: string;\n};\n\nexport const FileTreeFolder = ({\n path,\n name,\n className,\n children,\n ...props\n}: FileTreeFolderProps) => {\n const { expandedPaths, togglePath, selectedPath, onSelect } =\n useContext(FileTreeContext);\n const isExpanded = expandedPaths.has(path);\n const isSelected = selectedPath === path;\n\n const handleOpenChange = useCallback(() => {\n togglePath(path);\n }, [togglePath, path]);\n\n const handleSelect = useCallback(() => {\n togglePath(path);\n onSelect?.(path);\n }, [togglePath, onSelect, path]);\n\n const folderContextValue = useMemo(\n () => ({ isExpanded, name, path }),\n [isExpanded, name, path]\n );\n\n return (\n <FileTreeFolderContext.Provider value={folderContextValue}>\n <Collapsible onOpenChange={handleOpenChange} open={isExpanded}>\n <div\n className={cn(\"\", className)}\n {...props}\n >\n <div\n className={cn(\n \"flex w-full items-center gap-1 rounded px-2 py-1 text-left transition-colors hover:bg-muted/50\",\n isSelected && \"bg-muted\"\n )}\n >\n <CollapsibleTrigger asChild>\n <button\n className=\"flex shrink-0 cursor-pointer items-center border-none bg-transparent p-0\"\n type=\"button\"\n >\n <ChevronRightIcon\n className={cn(\n \"size-4 shrink-0 text-muted-foreground transition-transform\",\n isExpanded && \"rotate-90\"\n )}\n />\n </button>\n </CollapsibleTrigger>\n <button\n className=\"flex min-w-0 flex-1 cursor-pointer items-center gap-1 border-none bg-transparent p-0 text-left\"\n onClick={handleSelect}\n type=\"button\"\n >\n <FileTreeIcon>\n {isExpanded ? (\n <FolderOpenIcon className=\"size-4 text-primary\" />\n ) : (\n <FolderIcon className=\"size-4 text-primary\" />\n )}\n </FileTreeIcon>\n <FileTreeName>{name}</FileTreeName>\n </button>\n </div>\n <CollapsibleContent>\n <div className=\"ml-4 border-l pl-2\">{children}</div>\n </CollapsibleContent>\n </div>\n </Collapsible>\n </FileTreeFolderContext.Provider>\n );\n};\n\ninterface FileTreeFileContextType {\n path: string;\n name: string;\n}\n\nconst FileTreeFileContext = createContext<FileTreeFileContextType>({\n name: \"\",\n path: \"\",\n});\n\nexport type FileTreeFileProps = HTMLAttributes<HTMLButtonElement> & {\n path: string;\n name: string;\n icon?: ReactNode;\n};\n\nexport const FileTreeFile = ({\n path,\n name,\n icon,\n className,\n children,\n ...props\n}: FileTreeFileProps) => {\n const { selectedPath, onSelect } = useContext(FileTreeContext);\n const isSelected = selectedPath === path;\n\n const handleClick = useCallback(() => {\n onSelect?.(path);\n }, [onSelect, path]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n onSelect?.(path);\n }\n },\n [onSelect, path]\n );\n\n const fileContextValue = useMemo(() => ({ name, path }), [name, path]);\n\n return (\n <FileTreeFileContext.Provider value={fileContextValue}>\n <button\n type=\"button\"\n className={cn(\n \"flex w-full cursor-pointer items-center gap-1 rounded border-none bg-transparent px-2 py-1 text-left text-inherit transition-colors hover:bg-muted/50\",\n isSelected && \"bg-muted\",\n className\n )}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n {...props}\n >\n {children ?? (\n <>\n {/* Spacer for alignment */}\n <span className=\"size-4 shrink-0\" />\n <FileTreeIcon>\n {icon ?? <FileIcon className=\"size-4 text-muted-foreground\" />}\n </FileTreeIcon>\n <FileTreeName>{name}</FileTreeName>\n </>\n )}\n </button>\n </FileTreeFileContext.Provider>\n );\n};\n\nexport type FileTreeActionsProps = HTMLAttributes<HTMLDivElement>;\n\nconst stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();\n\nexport const FileTreeActions = ({\n className,\n children,\n ...props\n}: FileTreeActionsProps) => (\n <div\n className={cn(\"ml-auto flex items-center gap-1\", className)}\n onClick={stopPropagation}\n onKeyDown={stopPropagation}\n {...props}\n >\n {children}\n </div>\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,kBAAAA,uBAAsB;AAC/B,SAAS,UAAU,YAAY,UAAU,WAAAC,UAAS,gBAAgB,WAAW,cAAc;AAC3F,SAA2C,aAAAC,YAAW,WAAAC,UAAS,UAAAC,SAAQ,YAAAC,iBAAgB;;;ACFvF,SAAS,UAAU,sBAAsB;AACzC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,WAAW,gBAAgB,QAAQ,YAAAC,iBAAgB;;;ACR5D,eAAsB,yBACpB,WACA,UACA,UACA,cACA,aAA4B,MAAM,MACnB;AACf,MAAI;AACF,UAAM,SAAS,MAAM,gCAAgC,WAAW,UAAU,QAAQ;AAClF,QAAI,CAAC,WAAW,GAAG;AACjB;AAAA,IACF;AACA,iBAAa,MAAM;AAAA,EACrB,QAAQ;AAAA,EAER;AACF;;;ACXA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAqEC,SAmLE,UAnLF,KAmGI,YAnGJ;AA1DR,IAAM,OAAO,MAAM;AAAC;AAEpB,IAAM,kBAAkB,cAAmC;AAAA;AAAA,EAEzD,eAAe,oBAAI,IAAI;AAAA,EACvB,YAAY;AACd,CAAC;AAUM,IAAM,WAAW,CAAC;AAAA,EACvB,UAAU;AAAA,EACV,kBAAkB,oBAAI,IAAI;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAqB;AACnB,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAS,eAAe;AACxE,QAAM,gBAAgB,sBAAsB;AAE5C,QAAM,aAAa;AAAA,IACjB,CAAC,SAAiB;AAChB,YAAM,cAAc,IAAI,IAAI,aAAa;AACzC,UAAI,YAAY,IAAI,IAAI,GAAG;AACzB,oBAAY,OAAO,IAAI;AAAA,MACzB,OAAO;AACL,oBAAY,IAAI,IAAI;AAAA,MACtB;AACA,0BAAoB,WAAW;AAC/B,yBAAmB,WAAW;AAAA,IAChC;AAAA,IACA,CAAC,eAAe,gBAAgB;AAAA,EAClC;AAEA,QAAM,eAAe;AAAA,IACnB,OAAO,EAAE,eAAe,UAAU,cAAc,WAAW;AAAA,IAC3D,CAAC,eAAe,UAAU,cAAc,UAAU;AAAA,EACpD;AAEA,SACE,oBAAC,gBAAgB,UAAhB,EAAyB,OAAO,cAC/B;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA,MAAK;AAAA,MACJ,GAAG;AAAA,MAEJ,8BAAC,SAAI,WAAU,OAAO,UAAS;AAAA;AAAA,EACjC,GACF;AAEJ;AAIO,IAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA,GAAG;AACL,MACE,oBAAC,UAAK,WAAW,GAAG,YAAY,SAAS,GAAI,GAAG,OAC7C,UACH;AAKK,IAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA,GAAG;AACL,MACE,oBAAC,UAAK,WAAW,GAAG,YAAY,SAAS,GAAI,GAAG,OAC7C,UACH;AASF,IAAM,wBAAwB,cAAyC;AAAA,EACrE,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,MAAM;AACR,CAAC;AAwFD,IAAM,sBAAsB,cAAuC;AAAA,EACjE,MAAM;AAAA,EACN,MAAM;AACR,CAAC;AAgED,IAAM,kBAAkB,CAAC,MAA4B,EAAE,gBAAgB;AAEhE,IAAM,kBAAkB,CAAC;AAAA,EAC9B;AAAA,EACA;AAAA,EACA,GAAG;AACL,MACE;AAAA,EAAC;AAAA;AAAA,IACC,WAAW,GAAG,mCAAmC,SAAS;AAAA,IAC1D,SAAS;AAAA,IACT,WAAW;AAAA,IACV,GAAG;AAAA,IAEH;AAAA;AACH;;;AFlBS,SAkMC,YAAAC,WAlMD,OAAAC,MAKL,QAAAC,aALK;AAhQX,IAAM,YAAY;AAClB,IAAM,iBACJ;AACF,IAAM,mBAA2C;AAAA,EAC/C,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,UAAU;AAAA,EACV,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,OAAO;AAAA,EACP,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,GAAG;AAAA,EACH,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AACP;AAcO,SAASC,UAAS;AAAA,EACvB;AAAA,EACA,qBAAqB;AAAA,EACrB,eAAe;AAAA,EACf;AAAA,EACA,WAAW;AAAA,EACX,WAAW;AAAA,EACX;AAAA,EACA,cAAc;AAAA,EACd;AACF,GAAkB;AAChB,QAAM,eAAe,WAAW,CAAC,UAAU,MAAM,YAAY;AAC7D,QAAM,CAAC,cAAc,eAAe,IAAIC,UAAsB,oBAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;AACjF,QAAM,CAAC,cAAc,eAAe,IAAIA,UAA6B;AACrE,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,UAAwB,IAAI;AAC1E,QAAM,cAAc,aAAa,CAAC,MAAO,YAAa,EAAE,YAAY,SAAS,KAAK,QAAS,KAAM;AACjG,QAAM,cAAc,eAAe;AACnC,QAAM,mBAAmB,OAAO,WAAW;AAE3C,QAAM,oBAAoB,eAAe,CAAC,SAAsB;AAC9D,oBAAgB,IAAI;AACpB,2BAAuB,IAAI;AAAA,EAC7B,CAAC;AAED,YAAU,MAAM;AACd,QAAI,iBAAiB,WAAW,CAAC,eAAe,WAAW;AACzD,kBAAY,kBAAkB,EAAE,UAAU,CAAC,aAAa,SAAS,EAAE,CAAC;AAAA,IACtE;AACA,qBAAiB,UAAU;AAAA,EAC7B,GAAG,CAAC,aAAa,WAAW,WAAW,CAAC;AAExC,QAAM,6BAA6B,eAAe,CAAC,SAAsB;AACvE,2BAAuB,IAAI;AAAA,EAC7B,CAAC;AAGD,YAAU,MAAM;AACd,+BAA2B,YAAY;AAAA,EACzC,GAAG,CAAC,CAAC;AAEL,QAAM,uBAAuB,CAAC,SAAsB;AAClD,sBAAkB,IAAI;AAAA,EACxB;AAEA,QAAM,oBAAoB,CAAC,SAAiB;AAC1C,UAAM,OAAO,IAAI,IAAI,YAAY;AACjC,QAAI,KAAK,IAAI,IAAI,GAAG;AAClB,WAAK,OAAO,IAAI;AAAA,IAClB,OAAO;AACL,WAAK,IAAI,IAAI;AAAA,IACf;AACA,yBAAqB,IAAI;AAAA,EAC3B;AAEA,QAAM,uBAAuB,eAAe,CAAC,cAAsB,aAAsB;AACvF,oBAAgB,CAAC,YAAY;AAC3B,UAAI,CAAC,SAAS;AACZ,eAAO;AAAA,MACT;AACA,UAAI,YAAY,gBAAgB,QAAQ,WAAW,GAAG,YAAY,GAAG,GAAG;AACtE,YAAI,CAAC,UAAU;AACb,iBAAO;AAAA,QACT;AACA,eAAO,YAAY,eACf,WACA,GAAG,QAAQ,GAAG,QAAQ,MAAM,aAAa,MAAM,CAAC;AAAA,MACtD;AACA,aAAO;AAAA,IACT,CAAC;AAED,UAAM,eAAe,oBAAI,IAAY;AACrC,eAAW,QAAQ,cAAc;AAC/B,UAAI,SAAS,gBAAgB,KAAK,WAAW,GAAG,YAAY,GAAG,GAAG;AAChE,YAAI,UAAU;AACZ,uBAAa;AAAA,YACX,SAAS,eAAe,WAAW,GAAG,QAAQ,GAAG,KAAK,MAAM,aAAa,MAAM,CAAC;AAAA,UAClF;AAAA,QACF;AACA;AAAA,MACF;AACA,mBAAa,IAAI,IAAI;AAAA,IACvB;AACA,yBAAqB,YAAY;AAAA,EACnC,CAAC;AAED,QAAM;AAAA,IACJ,MAAM;AAAA,IACN,WAAW;AAAA,IACX,OAAO;AAAA,EACT,IAAI,SAAS;AAAA,IACX,UAAU,CAAC,aAAa,WAAW,QAAQ;AAAA,IAC3C,SAAS,MAAkB,QAAQ,WAAY,QAAQ;AAAA,IACvD,SAAS,CAAC,CAAC;AAAA,IACX,iBAAiB,cAAc,MAAS;AAAA,EAC1C,CAAC;AAED,QAAM,iBAAiB,eAAe,OAAO,MAAc,SAAiB;AAC1E,QAAI,CAAC,UAAW;AAChB,UAAM,mBAAmB;AACzB,uBAAmB,IAAI;AACvB,oBAAgB,IAAI;AACpB,QAAI;AACF,UAAI,YAAY;AACd,cAAM,WAAW,MAAM,IAAI;AAAA,MAC7B,WAAW,cAAc;AACvB,cAAM,UAAU,MAAM;AAAA,UACpB,iBAAiB,mBAAmB,SAAS,CAAC,UAAU,mBAAmB,IAAI,CAAC;AAAA,QAClF;AACA,aAAK;AACL,cAAM,gFAAmC;AAAA,MAC3C,OAAO;AACL,cAAM,yBAAyB,WAAW,MAAM,MAAM,cAAc,MAAM;AACxE,iBAAO,qBAAqB,gBAAgB,SAAS,EAAE,oBAAoB,mBAAmB;AAAA,QAChG,CAAC;AAAA,MACH;AAAA,IACF,UAAE;AACA,yBAAmB,CAAC,YAAa,YAAY,OAAO,OAAO,OAAQ;AAAA,IACrE;AAAA,EACF,CAAC;AAED,QAAM,eAAe,CAAC,SAAiB;AACrC,oBAAgB,IAAI;AAAA,EACtB;AAEA,MAAI,CAAC,WAAW;AACd,WAAO,gBAAAH,KAAC,cAAW,OAAM,wCAAS,aAAY,8FAAkB;AAAA,EAClE;AAEA,MAAI,aAAa;AACf,WACE,gBAAAC,MAAC,SAAI,WAAU,iFACb;AAAA,sBAAAD,KAAC,WAAQ,MAAM,IAAI,WAAU,gBAAe;AAAA,MAC5C,gBAAAA,KAAC,UAAK,mCAAM;AAAA,OACd;AAAA,EAEJ;AAEA,MAAI,WAAW;AACb,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,aAAa,qBAAqB,QAAQ,UAAU,UAAU;AAAA;AAAA,IAChE;AAAA,EAEJ;AAEA,MAAI,CAAC,eAAe,YAAY,WAAW,GAAG;AAC5C,WAAO,gBAAAA,KAAC,cAAW,OAAM,8CAAU,aAAY,kFAAgB;AAAA,EACjE;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV,kBAAkB;AAAA,MAClB;AAAA,MACA,UAAU;AAAA,MACV,WAAU;AAAA,MAET,sBAAY;AAAA,QAAI,CAAC,UAChB,MAAM,SACJ,gBAAAA;AAAA,UAAC;AAAA;AAAA,YAEC;AAAA,YACA;AAAA,YACA;AAAA,YACA,YAAY;AAAA,YACZ,cAAc;AAAA,YACd,aAAa;AAAA,YACb,kBAAkB;AAAA,YAClB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA;AAAA,UAbK,MAAM;AAAA,QAcb,IAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YAEC;AAAA,YACA,YAAY;AAAA,YACZ,cAAc;AAAA,YACd,kBAAkB;AAAA,YAClB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA;AAAA,UAVK,MAAM;AAAA,QAWb;AAAA,MAEJ;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAcG;AACD,QAAM,cAAc,eAAe;AACnC,QAAM,aAAa,aAAa,IAAI,MAAM,IAAI;AAC9C,QAAM,aAAa,iBAAiB,MAAM;AAC1C,QAAM,iBAAiB,OAAyB,IAAI;AACpD,QAAM,CAAC,YAAY,aAAa,IAAIG,UAAS,KAAK;AAClD,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAS,MAAM,IAAI;AAC7D,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAwD,IAAI;AAEpG,QAAM,cAA0B,kBAAkB,WAAW,MAAM,IAAI;AAEvE,YAAU,MAAM;AACd,QAAI,CAAC,WAAY,kBAAiB,MAAM,IAAI;AAAA,EAC9C,GAAG,CAAC,MAAM,MAAM,UAAU,CAAC;AAE3B,YAAU,MAAM;AACd,QAAI,CAAC,WAAY;AACjB,mBAAe,SAAS,MAAM;AAC9B,mBAAe,SAAS,OAAO;AAAA,EACjC,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,eAAe,eAAe,YAAY;AAC9C,UAAM,WAAW,cAAc,KAAK;AACpC,QAAI,CAAC,YAAY,aAAa,MAAM,MAAM;AACxC,oBAAc,KAAK;AACnB,uBAAiB,MAAM,IAAI;AAC3B;AAAA,IACF;AACA,oBAAgB,QAAQ;AACxB,QAAI;AACF,YAAM,SAAS,MAAkB,WAAW,WAAW,MAAM,MAAM,QAAQ;AAC3E,uBAAiB,MAAM,MAAM,OAAO,IAAI;AACxC,oBAAc,KAAK;AACnB,YAAM,YAAY,kBAAkB,EAAE,UAAU,CAAC,aAAa,SAAS,EAAE,CAAC;AAAA,IAC5E,SAAS,OAAO;AACd,YAAM,gBAAgB,OAAO,gCAAO,CAAC;AACrC,qBAAe,SAAS,MAAM;AAC9B,qBAAe,SAAS,OAAO;AAAA,IACjC,UAAE;AACA,sBAAgB,IAAI;AAAA,IACtB;AAAA,EACF,CAAC;AAED,QAAM,eAAe,MAAM;AACzB,kBAAc,KAAK;AACnB,qBAAiB,MAAM,IAAI;AAAA,EAC7B;AAEA,QAAM,aAAa,YAAY;AAC7B,oBAAgB,MAAM;AACtB,QAAI;AACF,YAAkB,SAAS,WAAW,MAAM,IAAI;AAChD,YAAM,YAAY,kBAAkB,EAAE,UAAU,CAAC,aAAa,SAAS,EAAE,CAAC;AAAA,IAC5E,SAAS,OAAO;AACd,YAAM,gBAAgB,OAAO,sCAAQ,CAAC;AAAA,IACxC,UAAE;AACA,sBAAgB,IAAI;AAAA,IACtB;AAAA,EACF;AAEA,QAAM,eAAe,YAAY;AAC/B,QAAI,CAAC,OAAO,QAAQ,wCAAU,MAAM,IAAI,eAAK,GAAG;AAC9C;AAAA,IACF;AACA,oBAAgB,QAAQ;AACxB,QAAI;AACF,YAAkB,WAAW,WAAW,MAAM,IAAI;AAClD,uBAAiB,MAAM,IAAI;AAC3B,YAAM,YAAY,kBAAkB,EAAE,UAAU,CAAC,aAAa,SAAS,EAAE,CAAC;AAAA,IAC5E,SAAS,OAAO;AACd,YAAM,gBAAgB,OAAO,sCAAQ,CAAC;AAAA,IACxC,UAAE;AACA,sBAAgB,IAAI;AAAA,IACtB;AAAA,EACF;AAEA,SACE,gBAAAH,KAAC,eAAY,MAAM,YAAY,cAAc,MAAM,YAAY,MAAM,IAAI,GACvE,0BAAAC,MAAC,SACC;AAAA,oBAAAA,MAAC,SAAI,WAAW,GAAG,gBAAgB,cAAc,UAAU,GACzD;AAAA,sBAAAD,KAAC,sBAAmB,SAAO,MACzB,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,OAAO,aAAa,6BAAS;AAAA,UAE7B,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,gBACA,cAAc;AAAA,cAChB;AAAA;AAAA,UACF;AAAA;AAAA,MACF,GACF;AAAA,MACC,aACC,gBAAAC,MAAAF,WAAA,EACE;AAAA,wBAAAC,KAAC,gBAAc,wBAAc,GAAE;AAAA,QAC/B,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,OAAO;AAAA,YACP,WAAU;AAAA,YACV,UAAU,iBAAiB;AAAA,YAC3B,QAAQ,MAAM,KAAK,aAAa;AAAA,YAChC,UAAU,CAAC,UAAU,iBAAiB,MAAM,OAAO,KAAK;AAAA,YACxD,SAAS,CAAC,UAAU,MAAM,gBAAgB;AAAA,YAC1C,WAAW,CAAC,UAAU;AACpB,oBAAM,gBAAgB;AACtB,kBAAI,MAAM,QAAQ,SAAS;AACzB,sBAAM,eAAe;AACrB,qBAAK,aAAa;AAAA,cACpB,WAAW,MAAM,QAAQ,UAAU;AACjC,sBAAM,eAAe;AACrB,6BAAa;AAAA,cACf;AAAA,YACF;AAAA;AAAA,QACF;AAAA,SACF,IAEA,gBAAAC;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS,MAAM;AACb,wBAAY,MAAM,IAAI;AACtB,yBAAa,MAAM,IAAI;AAAA,UACzB;AAAA,UAEA;AAAA,4BAAAD,KAAC,gBAAc,wBAAc,GAAE;AAAA,YAC/B,gBAAAA,KAAC,gBAAa,WAAU,kBAAkB,gBAAM,MAAK;AAAA;AAAA;AAAA,MACvD;AAAA,MAED,CAAC,WAAW,gBAAAC,MAAC,mBAAgB,WAAU,4CACtC;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,SAAS,MAAM;AACb,oBAAM,SAAS,SAAS,cAAc,GAAG;AACzC,qBAAO,OAAO;AACd,qBAAO,WAAW,GAAG,MAAM,IAAI;AAC/B,qBAAO,MAAM;AAAA,YACf;AAAA,YACA,OAAM;AAAA,YAEN,0BAAAA,KAAC,YAAS,MAAM,IAAI;AAAA;AAAA,QACtB;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,UAAU,iBAAiB;AAAA,YAC3B,SAAS,MAAM;AACb,2BAAa,MAAM,IAAI;AACvB,+BAAiB,MAAM,IAAI;AAC3B,4BAAc,IAAI;AAAA,YACpB;AAAA,YACA,OAAM;AAAA,YAEL,2BAAiB,WAAW,gBAAAA,KAAC,WAAQ,MAAM,IAAI,WAAU,gBAAe,IAAK,gBAAAA,KAAC,UAAO,MAAM,IAAI;AAAA;AAAA,QAClG;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,UAAU,iBAAiB;AAAA,YAC3B,SAAS,MAAM,KAAK,WAAW;AAAA,YAC/B,OAAM;AAAA,YAEL,2BAAiB,SAAS,gBAAAA,KAAC,WAAQ,MAAM,IAAI,WAAU,gBAAe,IAAK,gBAAAA,KAAC,QAAK,MAAM,IAAI;AAAA;AAAA,QAC9F;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,UAAU,iBAAiB,QAAQ,CAAC;AAAA,YACpC,SAAS,YAAY;AACnB,kBAAI,CAAC,YAAa;AAClB,8BAAgB,OAAO;AACvB,kBAAI;AACF,sBAAM,YAAY,MAAM,MAAM,MAAM,IAAI;AACxC,sBAAM,YAAY,kBAAkB,EAAE,UAAU,CAAC,aAAa,SAAS,EAAE,CAAC;AAAA,cAC5E,SAAS,OAAO;AACd,sBAAM,gBAAgB,OAAO,0BAAM,CAAC;AAAA,cACtC,UAAE;AACA,gCAAgB,IAAI;AAAA,cACtB;AAAA,YACF;AAAA,YACA,OAAM;AAAA,YAEL,2BAAiB,UAAU,gBAAAA,KAAC,WAAQ,MAAM,IAAI,WAAU,gBAAe,IAAK,gBAAAA,KAAC,SAAM,MAAM,IAAI;AAAA;AAAA,QAChG;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,UAAU,iBAAiB;AAAA,YAC3B,SAAS,MAAM,KAAK,aAAa;AAAA,YACjC,OAAM;AAAA,YAEL,2BAAiB,WAAW,gBAAAA,KAAC,WAAQ,MAAM,IAAI,WAAU,gBAAe,IAAK,gBAAAA,KAAC,UAAO,MAAM,IAAI;AAAA;AAAA,QAClG;AAAA,SACF,IAAqB,cACnB,gBAAAA,KAAC,mBAAgB,WAAU,4CACzB,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC,UAAU,iBAAiB;AAAA,UAC3B,SAAS,MAAM,KAAK,aAAa;AAAA,UACjC,OAAM;AAAA,UAEL,2BAAiB,WAAW,gBAAAA,KAAC,WAAQ,MAAM,IAAI,WAAU,gBAAe,IAAK,gBAAAA,KAAC,UAAO,MAAM,IAAI;AAAA;AAAA,MAClG,GACF,IACE;AAAA,OACN;AAAA,IACA,gBAAAA,KAAC,sBACC,0BAAAA,KAAC,SAAI,WAAU,sBACb,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,SAAS,MAAM;AAAA,QACf;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF,GACF,GACF;AAAA,KACF,GACF;AAEJ;AAEA,SAAS,SAAS;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAWG;AACD,QAAM,cAAc,aAAa,iBAAiB,SAAS,UAAU,mBAAmB,MAAM,IAAI,CAAC,EAAE;AACrG,QAAM,YAAY,oBAAoB,MAAM;AAC5C,QAAM,aAAa,iBAAiB,MAAM;AAC1C,QAAM,cAAc,eAAe;AACnC,QAAM,iBAAiB,OAAyB,IAAI;AACpD,QAAM,CAAC,YAAY,aAAa,IAAIG,UAAS,KAAK;AAClD,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAS,MAAM,IAAI;AAC7D,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAwD,IAAI;AAEpG,YAAU,MAAM;AACd,QAAI,CAAC,YAAY;AACf,uBAAiB,MAAM,IAAI;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,MAAM,MAAM,UAAU,CAAC;AAE3B,YAAU,MAAM;AACd,QAAI,CAAC,YAAY;AACf;AAAA,IACF;AACA,mBAAe,SAAS,MAAM;AAC9B,mBAAe,SAAS,OAAO;AAAA,EACjC,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,eAAe,eAAe,YAAY;AAC9C,UAAM,WAAW,cAAc,KAAK;AACpC,QAAI,CAAC,YAAY,aAAa,MAAM,MAAM;AACxC,oBAAc,KAAK;AACnB,uBAAiB,MAAM,IAAI;AAC3B;AAAA,IACF;AAEA,oBAAgB,QAAQ;AACxB,QAAI;AACF,YAAM,SAAS,MAAkB,WAAW,WAAW,MAAM,MAAM,QAAQ;AAC3E,uBAAiB,MAAM,MAAM,OAAO,IAAI;AACxC,oBAAc,KAAK;AACnB,YAAM,YAAY,kBAAkB,EAAE,UAAU,CAAC,aAAa,SAAS,EAAE,CAAC;AAAA,IAC5E,SAAS,OAAO;AACd,YAAM,gBAAgB,OAAO,gCAAO,CAAC;AACrC,qBAAe,SAAS,MAAM;AAC9B,qBAAe,SAAS,OAAO;AAAA,IACjC,UAAE;AACA,sBAAgB,IAAI;AAAA,IACtB;AAAA,EACF,CAAC;AAED,QAAM,eAAe,MAAM;AACzB,kBAAc,KAAK;AACnB,qBAAiB,MAAM,IAAI;AAAA,EAC7B;AAEA,QAAM,aAAa,YAAY;AAC7B,oBAAgB,MAAM;AACtB,QAAI;AACF,YAAkB,SAAS,WAAW,MAAM,IAAI;AAChD,YAAM,YAAY,kBAAkB,EAAE,UAAU,CAAC,aAAa,SAAS,EAAE,CAAC;AAAA,IAC5E,SAAS,OAAO;AACd,YAAM,gBAAgB,OAAO,sCAAQ,CAAC;AAAA,IACxC,UAAE;AACA,sBAAgB,IAAI;AAAA,IACtB;AAAA,EACF;AAEA,QAAM,eAAe,YAAY;AAC/B,QAAI,CAAC,OAAO,QAAQ,4BAAQ,MAAM,IAAI,eAAK,GAAG;AAC5C;AAAA,IACF;AACA,oBAAgB,QAAQ;AACxB,QAAI;AACF,YAAkB,WAAW,WAAW,MAAM,IAAI;AAClD,uBAAiB,MAAM,IAAI;AAC3B,YAAM,YAAY,kBAAkB,EAAE,UAAU,CAAC,aAAa,SAAS,EAAE,CAAC;AAAA,IAC5E,SAAS,OAAO;AACd,YAAM,gBAAgB,OAAO,sCAAQ,CAAC;AAAA,IACxC,UAAE;AACA,sBAAgB,IAAI;AAAA,IACtB;AAAA,EACF;AAEA,SACE,gBAAAF,MAAC,SAAI,WAAW,GAAG,gBAAgB,cAAc,UAAU,GACzD;AAAA,oBAAAD,KAAC,UAAK,WAAU,mBAAkB;AAAA,IAClC,gBAAAA,KAAC,gBAAc,sBAAY,MAAM,IAAI,GAAE;AAAA,IACtC,aACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,OAAO;AAAA,QACP,WAAU;AAAA,QACV,UAAU,iBAAiB;AAAA,QAC3B,QAAQ,MAAM,KAAK,aAAa;AAAA,QAChC,UAAU,CAAC,UAAU,iBAAiB,MAAM,OAAO,KAAK;AAAA,QACxD,SAAS,CAAC,UAAU,MAAM,gBAAgB;AAAA,QAC1C,WAAW,CAAC,UAAU;AACpB,gBAAM,gBAAgB;AACtB,cAAI,MAAM,QAAQ,SAAS;AACzB,kBAAM,eAAe;AACrB,iBAAK,aAAa;AAAA,UACpB,WAAW,MAAM,QAAQ,UAAU;AACjC,kBAAM,eAAe;AACrB,yBAAa;AAAA,UACf;AAAA,QACF;AAAA;AAAA,IACF,IAEA,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAM;AACb,uBAAa,MAAM,IAAI;AACvB,eAAK,WAAW,MAAM,MAAM,MAAM,IAAI;AAAA,QACxC;AAAA,QAEA;AAAA,0BAAAD,KAAC,gBAAa,WAAU,kBAAkB,gBAAM,MAAK;AAAA,UACrD,gBAAAA,KAAC,eAAY,MAAM,MAAM,MAAM;AAAA;AAAA;AAAA,IACjC;AAAA,IAED,YACC,gBAAAA,KAAC,WAAQ,MAAM,IAAI,WAAU,qEAAoE,IAC/F,CAAC,WACH,gBAAAC,MAAC,mBAAgB,WAAU,4CACzB;AAAA,sBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,SAAS,MAAM;AACb,kBAAM,SAAS,SAAS,cAAc,GAAG;AACzC,mBAAO,OAAO;AACd,mBAAO,WAAW,MAAM;AACxB,mBAAO,MAAM;AAAA,UACf;AAAA,UACA,OAAM;AAAA,UAEN,0BAAAA,KAAC,YAAS,MAAM,IAAI;AAAA;AAAA,MACtB;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,UAAU,iBAAiB;AAAA,UAC3B,SAAS,MAAM;AACb,yBAAa,MAAM,IAAI;AACvB,6BAAiB,MAAM,IAAI;AAC3B,0BAAc,IAAI;AAAA,UACpB;AAAA,UACA,OAAM;AAAA,UAEL,2BAAiB,WAChB,gBAAAA,KAAC,WAAQ,MAAM,IAAI,WAAU,gBAAe,IAE5C,gBAAAA,KAAC,UAAO,MAAM,IAAI;AAAA;AAAA,MAEtB;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,UAAU,iBAAiB;AAAA,UAC3B,SAAS,MAAM,KAAK,WAAW;AAAA,UAC/B,OAAM;AAAA,UAEL,2BAAiB,SAAS,gBAAAA,KAAC,WAAQ,MAAM,IAAI,WAAU,gBAAe,IAAK,gBAAAA,KAAC,QAAK,MAAM,IAAI;AAAA;AAAA,MAC9F;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,UAAU,iBAAiB,QAAQ,CAAC;AAAA,UACpC,SAAS,YAAY;AACnB,gBAAI,CAAC,YAAa;AAClB,4BAAgB,OAAO;AACvB,gBAAI;AACF,oBAAM,YAAY,MAAM,MAAM,MAAM,IAAI;AACxC,oBAAM,YAAY,kBAAkB,EAAE,UAAU,CAAC,aAAa,SAAS,EAAE,CAAC;AAAA,YAC5E,SAAS,OAAO;AACd,oBAAM,gBAAgB,OAAO,0BAAM,CAAC;AAAA,YACtC,UAAE;AACA,8BAAgB,IAAI;AAAA,YACtB;AAAA,UACF;AAAA,UACA,OAAM;AAAA,UAEL,2BAAiB,UAAU,gBAAAA,KAAC,WAAQ,MAAM,IAAI,WAAU,gBAAe,IAAK,gBAAAA,KAAC,SAAM,MAAM,IAAI;AAAA;AAAA,MAChG;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,UAAU,iBAAiB;AAAA,UAC3B,SAAS,MAAM,KAAK,aAAa;AAAA,UACjC,OAAM;AAAA,UAEL,2BAAiB,WAChB,gBAAAA,KAAC,WAAQ,MAAM,IAAI,WAAU,gBAAe,IAE5C,gBAAAA,KAAC,UAAO,MAAM,IAAI;AAAA;AAAA,MAEtB;AAAA,OACF,IACE,cACF,gBAAAA,KAAC,mBAAgB,WAAU,4CACzB,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,UAAU,iBAAiB;AAAA,QAC3B,SAAS,MAAM,KAAK,aAAa;AAAA,QACjC,OAAM;AAAA,QAEL,2BAAiB,WAAW,gBAAAA,KAAC,WAAQ,MAAM,IAAI,WAAU,gBAAe,IAAK,gBAAAA,KAAC,UAAO,MAAM,IAAI;AAAA;AAAA,IAClG,GACF,IACE;AAAA,KACN;AAEJ;AAEA,SAAS,gBAAgB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAcG;AACD,QAAM;AAAA,IACJ,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACF,IAAI,SAAS;AAAA,IACX,UAAU,CAAC,aAAa,WAAW,OAAO;AAAA,IAC1C,SAAS,MAAkB,QAAQ,WAAW,OAAO;AAAA,IACrD,iBAAiB,cAAc,MAAS;AAAA,EAC1C,CAAC;AAED,MAAI,WAAW;AACb,WACE,gBAAAC,MAAC,SAAI,WAAU,iFACb;AAAA,sBAAAD,KAAC,WAAQ,MAAM,IAAI,WAAU,gBAAe;AAAA,MAC5C,gBAAAA,KAAC,UAAK,mCAAM;AAAA,OACd;AAAA,EAEJ;AACA,MAAI,OAAO;AACT,WACE,gBAAAA,KAAC,SAAI,WAAU,yDACZ,2BAAiB,QAAQ,MAAM,UAAU,4BAC5C;AAAA,EAEJ;AACA,MAAI,CAAC,WAAW,QAAQ,WAAW,GAAG;AACpC,WAAO,gBAAAA,KAAC,SAAI,WAAU,yDAAwD,gCAAG;AAAA,EACnF;AAEA,SACE,gBAAAA,KAAAD,WAAA,EACG,kBAAQ;AAAA,IAAI,CAAC,UACZ,MAAM,SACJ,gBAAAC;AAAA,MAAC;AAAA;AAAA,QAEC,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,MAbK,MAAM;AAAA,IAcb,IAEA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QAEC,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,MAVK,MAAM;AAAA,IAWb;AAAA,EAEJ,GACF;AAEJ;AAEA,SAAS,YAAY,EAAE,KAAK,GAAwB;AAClD,MAAI,CAAC,QAAQ,KAAK,WAAW,EAAG,QAAO;AACvC,SACE,gBAAAA,KAAC,UAAK,WAAU,iDACb,eAAK,IAAI,CAAC,QACT,gBAAAA;AAAA,IAAC;AAAA;AAAA,MAEC,WAAU;AAAA,MACV,OAAO;AAAA,MAEN;AAAA;AAAA,IAJI;AAAA,EAKP,CACD,GACH;AAEJ;AAEA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AACF,GAKG;AACD,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAU;AAAA,MAET;AAAA;AAAA,EACH;AAEJ;AAEA,SAAS,WAAW,EAAE,OAAO,YAAY,GAA2C;AAClF,SACE,gBAAAC,MAAC,SAAI,WAAU,yFACb;AAAA,oBAAAD,KAAC,SAAI,WAAU,kFACZ,wBAAc,GACjB;AAAA,IACA,gBAAAC,MAAC,SAAI,WAAU,aACb;AAAA,sBAAAD,KAAC,SAAI,WAAU,qDAAqD,iBAAM;AAAA,MAC1E,gBAAAA,KAAC,SAAI,WAAU,+CAA+C,uBAAY;AAAA,OAC5E;AAAA,KACF;AAEJ;AAEA,SAAS,YAAY,UAA6B;AAChD,QAAM,MAAM,SAAS,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY,KAAK;AACxD,QAAM,QAAQ,iBAAiB,GAAG;AAClC,QAAM,MAAM,QAAQ,eAAe,KAAK,IAAI,GAAG,SAAS;AACxD,SAAO,gBAAAA,KAAC,gBAAa,KAAU,KAAK,GAAG,OAAO,MAAM,iBAAO;AAC7D;AAEA,SAAS,gBAA2B;AAClC,SAAO,gBAAAA,KAAC,gBAAa,KAAI,0BAAyB,KAAI,sBAAM;AAC9D;AAEA,SAAS,aAAa,EAAE,KAAK,IAAI,GAAiC;AAChE,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,WAAU;AAAA,MACV,WAAW;AAAA,MACX,SAAQ;AAAA;AAAA,EACV;AAEJ;AAEA,SAAS,gBAAgB,OAAgB,UAA0B;AACjE,MAAI,iBAAiB,SAAS,MAAM,SAAS;AAC3C,WAAO,MAAM;AAAA,EACf;AACA,SAAO;AACT;;;ADvzBiB,gBAAAI,MAGP,QAAAC,aAHO;AAhJjB,IAAM,iBAA+E,CAAC;AAE/E,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AACF,GAA6B;AAC3B,QAAM,CAAC,cAAc,eAAe,IAAIC,UAAsB,oBAAI,IAAI,CAAC;AACvE,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAS,KAAK;AACpD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAuB,OAAO;AAChE,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,KAAK;AAChD,QAAM,cAAcC,gBAAe;AACnC,QAAM,eAAeC,QAAyB,IAAI;AAClD,QAAM,iBAAiBA,QAAyB,IAAI;AACpD,QAAM,WAAW;AAAA,IAAa,CAAC,UAC7B,YAAa,MAAM,SAAS,SAAS,KAAK,iBAAkB;AAAA,EAC9D;AACA,QAAM,eAAe,WAAW,CAAC,UAAU,MAAM,YAAY;AAE7D,QAAM,kBAAkBC,SAA8B,MAAM;AAC1D,QAAI,CAAC,UAAW,QAAO,CAAC;AACxB,WAAO,SAAS;AAAA,MAAQ,CAAC,SAAS,kBAC/B,QAAQ,UAAU,CAAC,GAAG,QAAQ,CAAC,OAAO,eAAqC;AAC1E,YAAI,MAAM,SAAS,aAAa,CAAC,SAAS,MAAM,OAAO,KAAK,MAAM,QAAQ,WAAW,UAAU;AAC7F,iBAAO,CAAC;AAAA,QACV;AAEA,cAAM,KAAK,MAAM;AACjB,cAAM,OAAO,GAAG,eAAe,kBAAkB;AACjD,cAAM,UAAU,GAAG,gBAAgB,GAAG,eAAe,GAAG,eAAe;AACvE,YAAI,CAAC,QAAS,QAAO,CAAC;AAEtB,cAAMC,SACJ,GAAG,UACF,OAAO,MAAM,iBAAiB,YAAY,MAAM,aAAa,KAAK,EAAE,SAAS,IAC1E,MAAM,eACN;AACN,cAAM,MAAM,GAAG,QAAQ,YAAY,QAAQ,aAAa,YAAY,IAAI,MAAM,gBAAgB,IAAI,IAAI,UAAU;AAEhH,eAAO;AAAA,UACL;AAAA,YACE;AAAA,YACA,OAAAA;AAAA,YACA,QAAQ;AAAA,cACN;AAAA,cACA;AAAA,cACA,OAAAA;AAAA,cACA;AAAA,cACA,iBAAiB;AAAA,YACnB;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,UAAU,SAAS,CAAC;AAExB,EAAAC,WAAU,MAAM;AACd,QAAI,cAAc,eAAe,gBAAgB,WAAW,GAAG;AAC7D,mBAAa,OAAO;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,WAAW,gBAAgB,MAAM,CAAC;AAEtC,QAAM,kBAAkB,MAAM;AAC5B,UAAM,aAAa,MAAM,KAAK,YAAY,EACvC,OAAO,CAAC,SAAS,SAAS,GAAG,EAC7B,OAAO,CAAC,SAAS;AAChB,YAAM,QAAQ,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AAC5C,eAAS,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GAAG;AACpD,cAAM,WAAW,MAAM,MAAM,GAAG,KAAK,EAAE,KAAK,GAAG;AAC/C,YAAI,CAAC,aAAa,IAAI,QAAQ,EAAG,QAAO;AAAA,MAC1C;AACA,aAAO;AAAA,IACT,CAAC;AAEH,QAAI,WAAW,WAAW,GAAG;AAC3B,aAAO;AAAA,IACT;AAEA,WAAO,WAAW,OAAO,CAAC,aAAa,gBAAgB;AACrD,YAAM,eAAe,YAAY,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE;AAC5D,YAAM,eAAe,YAAY,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE;AAC5D,aAAO,eAAe,eAAe,cAAc;AAAA,IACrD,GAAG,WAAW,CAAC,KAAK,GAAG;AAAA,EACzB;AAEA,QAAM,qBAAqB,OAAO,UAAyC;AACzE,UAAM,QAAQ,MAAM,OAAO;AAC3B,QAAI,CAAC,aAAa,CAAC,SAAS,MAAM,WAAW,GAAG;AAC9C,YAAM,OAAO,QAAQ;AACrB;AAAA,IACF;AAEA,mBAAe,IAAI;AACnB,QAAI;AACF,YAAM,YAAY,gBAAgB;AAClC,YAAM,SAAS,MAAM,YAAY,WAAW,WAAW,KAAK;AAC5D,YAAM,YAAY,kBAAkB;AAAA,QAClC,UAAU,CAAC,aAAa,SAAS;AAAA,QACjC,aAAa;AAAA,MACf,CAAC;AACD,YAAM,YAAY,eAAe;AAAA,QAC/B,UAAU,CAAC,aAAa,SAAS;AAAA,QACjC,MAAM;AAAA,MACR,CAAC;AAED,UAAI,cAAc,KAAK;AACrB,wBAAgB,CAAC,SAAS;AACxB,gBAAM,OAAO,IAAI,IAAI,IAAI;AACzB,eAAK,IAAI,SAAS;AAClB,iBAAO;AAAA,QACT,CAAC;AAAA,MACH;AAEA,UAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,cAAM,qDAAa,OAAO,OAAO,KAAK,IAAI,CAAC,EAAE;AAAA,MAC/C;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,uBAAuB,KAAK;AAC1C,YAAM,sCAAQ;AAAA,IAChB,UAAE;AACA,qBAAe,KAAK;AACpB,YAAM,OAAO,QAAQ;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,oBAAoB,MAAM;AAC9B,iBAAa,SAAS,MAAM;AAAA,EAC9B;AAEA,QAAM,0BAA0B,MAAM;AACpC,mBAAe,SAAS,MAAM;AAAA,EAChC;AAEA,SACE,gBAAAN,MAAC,SAAI,WAAW,GAAG,iBAAiB,SAAS,GAC1C;AAAA,cAAU,gBAAAD,KAAC,SAAI,WAAU,QAAQ,mBAAQ,IAAS;AAAA,IACnD,gBAAAC,MAAC,SAAI,WAAU,yDACb;AAAA,sBAAAA,MAAC,SAAI,WAAU,sGACb;AAAA,wBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM,aAAa,OAAO;AAAA,YACnC,WAAW;AAAA,cACT;AAAA,cACA,cAAc,UACV,wEACA;AAAA,YACN;AAAA,YAEA;AAAA,8BAAAD,KAAC,cAAW,MAAM,IAAI;AAAA,cACrB;AAAA;AAAA;AAAA,QACH;AAAA,QACC,gBAAgB,SAAS,IACxB,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM,aAAa,WAAW;AAAA,YACvC,WAAW;AAAA,cACT;AAAA,cACA,cAAc,cACV,wEACA;AAAA,YACN;AAAA,YAEA;AAAA,8BAAAD,KAAC,kBAAe,MAAM,IAAI;AAAA,cAAE;AAAA,cAE5B,gBAAAA,KAAC,UAAK,WAAU,6DACb,0BAAgB,QACnB;AAAA;AAAA;AAAA,QACF,IACE;AAAA,SACN;AAAA,MACC,SAAS,gBAAAA,KAAC,SAAI,WAAU,2BACvB,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,UAAU,CAAC,aAAa;AAAA,UACxB,SAAS,YAAY;AACnB,yBAAa,IAAI;AACjB,gBAAI;AACF,oBAAM,OAAO;AACb,oBAAM,YAAY,kBAAkB;AAAA,gBAClC,UAAU,CAAC,aAAa,SAAS;AAAA,gBACjC,aAAa;AAAA,cACf,CAAC;AAAA,YACH,UAAE;AACA,2BAAa,KAAK;AAAA,YACpB;AAAA,UACF;AAAA,UACA,WAAU;AAAA,UACV,OAAM;AAAA,UAEL,sBAAY,gBAAAA,KAACQ,UAAA,EAAQ,MAAM,IAAI,WAAU,gBAAe,IAAK,gBAAAR,KAAC,aAAU,MAAM,IAAI;AAAA;AAAA,MACrF,GACF,IAAS;AAAA,MACR,CAAC,YAAY,cAAc,UAAU,gBAAAC,MAAC,SAAI,WAAU,2BACnD;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,UAAU,CAAC,aAAa;AAAA,YACxB,SAAS;AAAA,YACT,WAAU;AAAA,YACV,OAAM;AAAA,YAEL,wBAAc,gBAAAA,KAACQ,UAAA,EAAQ,MAAM,IAAI,WAAU,gBAAe,IAAK,gBAAAR,KAAC,UAAO,MAAM,IAAI;AAAA;AAAA,QACpF;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,UAAU,CAAC,aAAa;AAAA,YACxB,SAAS;AAAA,YACT,WAAU;AAAA,YACV,OAAM;AAAA,YAEL,wBAAc,gBAAAA,KAACQ,UAAA,EAAQ,MAAM,IAAI,WAAU,gBAAe,IAAK,gBAAAR,KAAC,YAAS,MAAM,IAAI;AAAA;AAAA,QACtF;AAAA,SACF,IAAS;AAAA,OACX;AAAA,IACC,cAAc,eAAe,gBAAgB,SAAS,IACrD,gBAAAA,KAAC,SAAI,WAAW,GAAG,yBAAyB,sBAAsB,GAChE,0BAAAA,KAAC,SAAI,WAAU,yBACZ,0BAAgB,IAAI,CAAC,MAAM,UAC1B,gBAAAC;AAAA,MAAC;AAAA;AAAA,QAEC,MAAK;AAAA,QACL,SAAS,MAAM,aAAa,KAAK,MAAM;AAAA,QACvC,WAAU;AAAA,QACV,OAAO,KAAK;AAAA,QAEZ;AAAA,0BAAAD,KAAC,YAAS,MAAM,IAAI,WAAU,uCAAsC;AAAA,UACpE,gBAAAA,KAAC,UAAK,WAAU,yDACb,eAAK,OACR;AAAA,UACA,gBAAAA,KAAC,UAAK,WAAU,sEACb,kBAAQ,GACX;AAAA;AAAA;AAAA,MAZK,KAAK;AAAA,IAaZ,CACD,GACH,GACF,IAEA,gBAAAA,KAAC,SAAI,WAAW,wBACd,0BAAAA;AAAA,MAACS;AAAA,MAAA;AAAA,QAEC;AAAA,QACA;AAAA,QACA,sBAAsB;AAAA,QACtB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,MARK,aAAa;AAAA,IASpB,GACF;AAAA,IAEF,gBAAAT;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,MAAK;AAAA,QACL,UAAQ;AAAA,QACR,WAAU;AAAA,QACV,UAAU;AAAA;AAAA,IACZ;AAAA,IACA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,MAAK;AAAA,QACL,UAAQ;AAAA,QACR,WAAU;AAAA,QACV,UAAU;AAAA,QAET,GAAI,EAAE,iBAAiB,GAAG;AAAA;AAAA,IAC7B;AAAA,KACF;AAEJ;","names":["useQueryClient","Loader2","useEffect","useMemo","useRef","useState","useState","Fragment","jsx","jsxs","FileTree","useState","jsx","jsxs","useState","useQueryClient","useRef","useMemo","title","useEffect","Loader2","FileTree"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/react/components/workspace/WorkspaceFilesPanel.tsx","../../../../src/react/components/workspace/FileTree.tsx","../../../../src/react/lib/open-session-file.ts","../../../../src/react/components/ai-elements/file-tree.tsx","../../../../src/react/components/workspace/file-icon-assets.ts"],"sourcesContent":["import { useQueryClient } from \"@tanstack/react-query\"\nimport { FileText, FolderTree, FolderUp, Loader2, PanelRightOpen, RefreshCw, Upload } from \"lucide-react\"\nimport { type ChangeEvent, type ReactNode, useEffect, useMemo, useRef, useState } from \"react\"\nimport { uploadFiles } from \"../../api/sessions\"\nimport { isUiMeta } from \"../../lib/ui-meta\"\nimport { cn } from \"../../lib/utils\"\nimport type { PreviewTarget } from \"../../stores/ui-store\"\nimport { useChatStore } from \"../../stores/chat-store\"\nimport { useUiStore } from \"../../stores/ui-store\"\nimport { FileTree } from \"./FileTree\"\n\ninterface WorkspaceFilesPanelProps {\n sessionId: string | null\n enableEditor?: boolean\n className?: string\n treeContainerClassName?: string\n title?: string\n rootPath?: string\n readOnly?: boolean\n onShareFile?: (path: string, name: string) => Promise<void>\n onSync?: () => Promise<void>\n allowDelete?: boolean\n /** Optional slot above the file tree (e.g. phase progress in host app). */\n topSlot?: ReactNode\n /** Custom file open handler; used when enableEditor is false if provided. */\n onOpenFile?: (path: string, name: string) => Promise<void>\n}\n\ntype WorkspaceTab = \"files\" | \"resources\"\n\ninterface InlineResourceItem {\n key: string\n title: string\n target: PreviewTarget\n}\n\nconst EMPTY_MESSAGES: ReturnType<typeof useChatStore.getState>[\"messages\"][string] = []\n\nexport function WorkspaceFilesPanel({\n sessionId,\n enableEditor = false,\n className,\n treeContainerClassName,\n title = \"工作区\",\n rootPath = \".\",\n readOnly = false,\n onShareFile,\n onSync,\n allowDelete = false,\n topSlot,\n onOpenFile,\n}: WorkspaceFilesPanelProps) {\n const [expandedDirs, setExpandedDirs] = useState<Set<string>>(new Set())\n const [isUploading, setIsUploading] = useState(false)\n const [activeTab, setActiveTab] = useState<WorkspaceTab>(\"files\")\n const [isSyncing, setIsSyncing] = useState(false)\n const queryClient = useQueryClient()\n const fileInputRef = useRef<HTMLInputElement>(null)\n const folderInputRef = useRef<HTMLInputElement>(null)\n const messages = useChatStore((state) =>\n sessionId ? (state.messages[sessionId] ?? EMPTY_MESSAGES) : EMPTY_MESSAGES,\n )\n const pushArtifact = useUiStore((state) => state.pushArtifact)\n\n const inlineResources = useMemo<InlineResourceItem[]>(() => {\n if (!sessionId) return []\n return messages.flatMap((message, messageIndex) =>\n (message.blocks ?? []).flatMap((block, blockIndex): InlineResourceItem[] => {\n if (block.type !== \"tool_ui\" || !isUiMeta(block.content) || block.content.target !== \"inline\") {\n return []\n }\n\n const ui = block.content\n const type = ui.resourceHTML ? \"resource-html\" : \"resource-uri\"\n const content = ui.resourceHTML ?? ui.resourceUri ?? ui.resourceURI ?? \"\"\n if (!content) return []\n\n const title =\n ui.title ??\n (typeof block.display_name === \"string\" && block.display_name.trim().length > 0\n ? block.display_name\n : \"可视化产物\")\n const key = `${message.entry_id ?? message.timestamp ?? messageIndex}-${block.tool_call_id ?? \"ui\"}-${blockIndex}`\n\n return [\n {\n key,\n title,\n target: {\n type,\n content,\n title,\n key,\n bridgeSessionId: sessionId,\n },\n },\n ]\n }),\n )\n }, [messages, sessionId])\n\n useEffect(() => {\n if (activeTab === \"resources\" && inlineResources.length === 0) {\n setActiveTab(\"files\")\n }\n }, [activeTab, inlineResources.length])\n\n const uploadTargetDir = () => {\n const candidates = Array.from(expandedDirs)\n .filter((path) => path !== \".\")\n .filter((path) => {\n const parts = path.split(\"/\").filter(Boolean)\n for (let index = 1; index < parts.length; index += 1) {\n const ancestor = parts.slice(0, index).join(\"/\")\n if (!expandedDirs.has(ancestor)) return false\n }\n return true\n })\n\n if (candidates.length === 0) {\n return \".\"\n }\n\n return candidates.reduce((deepestPath, currentPath) => {\n const deepestDepth = deepestPath.split(\"/\").filter(Boolean).length\n const currentDepth = currentPath.split(\"/\").filter(Boolean).length\n return currentDepth > deepestDepth ? currentPath : deepestPath\n }, candidates[0] ?? \".\")\n }\n\n const handleUploadChange = async (event: ChangeEvent<HTMLInputElement>) => {\n const files = event.target.files\n if (!sessionId || !files || files.length === 0) {\n event.target.value = \"\"\n return\n }\n\n setIsUploading(true)\n try {\n const targetDir = uploadTargetDir()\n const result = await uploadFiles(sessionId, targetDir, files)\n await queryClient.invalidateQueries({\n queryKey: [\"file-tree\", sessionId],\n refetchType: \"all\",\n })\n await queryClient.refetchQueries({\n queryKey: [\"file-tree\", sessionId],\n type: \"active\",\n })\n\n if (targetDir !== \".\") {\n setExpandedDirs((prev) => {\n const next = new Set(prev)\n next.add(targetDir)\n return next\n })\n }\n\n if (result.failed.length > 0) {\n alert(`部分文件上传失败: ${result.failed.join(\", \")}`)\n }\n } catch (error) {\n console.error(\"Upload files failed\", error)\n alert(\"上传文件失败\")\n } finally {\n setIsUploading(false)\n event.target.value = \"\"\n }\n }\n\n const handleUploadClick = () => {\n fileInputRef.current?.click()\n }\n\n const handleFolderUploadClick = () => {\n folderInputRef.current?.click()\n }\n\n return (\n <div className={cn(\"flex flex-col\", className)}>\n {topSlot ? <div className=\"mb-3\">{topSlot}</div> : null}\n <div className=\"mb-2 flex shrink-0 items-center justify-between gap-2\">\n <div className=\"flex min-w-0 items-center gap-1 rounded-lg bg-[hsl(var(--muted))]/60 p-0.5 text-[11px] font-medium\">\n <button\n type=\"button\"\n onClick={() => setActiveTab(\"files\")}\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-md px-2 py-1 transition-colors\",\n activeTab === \"files\"\n ? \"bg-[hsl(var(--background))] text-[hsl(var(--foreground))] shadow-sm\"\n : \"text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]\",\n )}\n >\n <FolderTree size={12} />\n {title}\n </button>\n {inlineResources.length > 0 ? (\n <button\n type=\"button\"\n onClick={() => setActiveTab(\"resources\")}\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-md px-2 py-1 transition-colors\",\n activeTab === \"resources\"\n ? \"bg-[hsl(var(--background))] text-[hsl(var(--foreground))] shadow-sm\"\n : \"text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]\",\n )}\n >\n <PanelRightOpen size={12} />\n 可视化产物\n <span className=\"font-mono text-[10px] text-[hsl(var(--muted-foreground))]\">\n {inlineResources.length}\n </span>\n </button>\n ) : null}\n </div>\n {onSync ? <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n disabled={!sessionId || isSyncing}\n onClick={async () => {\n setIsSyncing(true)\n try {\n await onSync()\n await queryClient.invalidateQueries({\n queryKey: [\"file-tree\", sessionId],\n refetchType: \"all\",\n })\n } finally {\n setIsSyncing(false)\n }\n }}\n className=\"rounded p-1 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--muted-foreground))/10] hover:text-[hsl(var(--foreground))] disabled:cursor-not-allowed disabled:opacity-50\"\n title=\"同步共享区\"\n >\n {isSyncing ? <Loader2 size={12} className=\"animate-spin\" /> : <RefreshCw size={12} />}\n </button>\n </div> : null}\n {!readOnly && activeTab === \"files\" ? <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n disabled={!sessionId || isUploading}\n onClick={handleUploadClick}\n className=\"rounded p-1 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--muted-foreground))/10] hover:text-[hsl(var(--foreground))] disabled:cursor-not-allowed disabled:opacity-50\"\n title=\"上传文件\"\n >\n {isUploading ? <Loader2 size={12} className=\"animate-spin\" /> : <Upload size={12} />}\n </button>\n <button\n type=\"button\"\n disabled={!sessionId || isUploading}\n onClick={handleFolderUploadClick}\n className=\"rounded p-1 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--muted-foreground))/10] hover:text-[hsl(var(--foreground))] disabled:cursor-not-allowed disabled:opacity-50\"\n title=\"上传文件夹\"\n >\n {isUploading ? <Loader2 size={12} className=\"animate-spin\" /> : <FolderUp size={12} />}\n </button>\n </div> : null}\n </div>\n {activeTab === \"resources\" && inlineResources.length > 0 ? (\n <div className={cn(\"min-h-0 overflow-auto\", treeContainerClassName)}>\n <div className=\"flex flex-col gap-1.5\">\n {inlineResources.map((item, index) => (\n <button\n key={item.key}\n type=\"button\"\n onClick={() => pushArtifact(item.target)}\n className=\"group flex min-w-0 items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm transition-colors hover:bg-[hsl(var(--muted))]\"\n title={item.title}\n >\n <FileText size={14} className=\"shrink-0 text-[hsl(var(--primary))]\" />\n <span className=\"min-w-0 flex-1 truncate text-[hsl(var(--foreground))]\">\n {item.title}\n </span>\n <span className=\"shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]\">\n {index + 1}\n </span>\n </button>\n ))}\n </div>\n </div>\n ) : (\n <div className={treeContainerClassName}>\n <FileTree\n key={sessionId ?? \"workspace-empty\"}\n sessionId={sessionId}\n enableEditor={enableEditor}\n onExpandedDirsChange={setExpandedDirs}\n rootPath={rootPath}\n readOnly={readOnly}\n onShareFile={onShareFile}\n allowDelete={allowDelete}\n onOpenFile={onOpenFile}\n />\n </div>\n )}\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple\n className=\"hidden\"\n onChange={handleUploadChange}\n />\n <input\n ref={folderInputRef}\n type=\"file\"\n multiple\n className=\"hidden\"\n onChange={handleUploadChange}\n // biome-ignore lint/suspicious/noExplicitAny: webkitdirectory is a non-standard HTML attribute\n {...({ webkitdirectory: \"\" } as any)}\n />\n </div>\n )\n}\n","import { useQuery, useQueryClient } from \"@tanstack/react-query\"\nimport {\n ChevronRight,\n Copy,\n Download,\n Link2,\n Loader2,\n Pencil,\n Trash2,\n} from \"lucide-react\"\nimport type { ReactNode } from \"react\"\nimport { useEffect, useEffectEvent, useRef, useState } from \"react\"\nimport * as sessionsApi from \"../../api/sessions\"\nimport { apiFetchText } from \"../../api/client\"\nimport { getAuthedUrl } from \"../../api/client\"\nimport { openSessionFileInPreview } from \"../../lib/open-session-file\"\nimport { cn } from \"../../lib/utils\"\nimport { useChatStore } from \"../../stores/chat-store\"\nimport { useSessionStore } from \"../../stores/session-store\"\nimport { useUiStore } from \"../../stores/ui-store\"\nimport { FileTree as AIFileTree, FileTreeActions, FileTreeIcon, FileTreeName } from \"../ai-elements/file-tree\"\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"../ui/collapsible\"\nimport { FILE_ICON_ASSETS, FOLDER_ICON_ASSET, GENERIC_FILE_ICON_ASSET } from \"./file-icon-assets\"\n\ntype FileEntry = Awaited<ReturnType<typeof sessionsApi.listDir>>[number]\n\nconst ROOT_PATH = \".\"\nconst TREE_ROW_CLASS =\n \"group flex w-full items-center gap-1 rounded px-2 py-1 text-left transition-colors hover:bg-muted/50\"\n\ninterface FileTreeProps {\n sessionId: string | null\n checkActiveSession?: boolean\n enableEditor?: boolean\n onExpandedDirsChange?: (dirs: Set<string>) => void\n rootPath?: string\n readOnly?: boolean\n onShareFile?: (path: string, name: string) => Promise<void>\n allowDelete?: boolean\n onOpenFile?: (path: string, name: string) => Promise<void>\n}\n\nexport function FileTree({\n sessionId,\n checkActiveSession = true,\n enableEditor = false,\n onExpandedDirsChange,\n rootPath = ROOT_PATH,\n readOnly = false,\n onShareFile,\n allowDelete = false,\n onOpenFile,\n}: FileTreeProps) {\n const pushArtifact = useUiStore((state) => state.pushArtifact)\n const [expandedDirs, setExpandedDirs] = useState<Set<string>>(new Set([rootPath]))\n const [selectedPath, setSelectedPath] = useState<string | undefined>()\n const [openingFilePath, setOpeningFilePath] = useState<string | null>(null)\n const isStreaming = useChatStore((s) => (sessionId ? (s.isStreaming[sessionId] ?? false) : false))\n const queryClient = useQueryClient()\n const prevStreamingRef = useRef(isStreaming)\n\n const applyExpandedDirs = useEffectEvent((dirs: Set<string>) => {\n setExpandedDirs(dirs)\n onExpandedDirsChange?.(dirs)\n })\n\n useEffect(() => {\n if (prevStreamingRef.current && !isStreaming && sessionId) {\n queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n }\n prevStreamingRef.current = isStreaming\n }, [isStreaming, sessionId, queryClient])\n\n const onExpandedDirsChangeStable = useEffectEvent((dirs: Set<string>) => {\n onExpandedDirsChange?.(dirs)\n })\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: mount-only effect, intentionally empty deps\n useEffect(() => {\n onExpandedDirsChangeStable(expandedDirs)\n }, [])\n\n const handleExpandedChange = (dirs: Set<string>) => {\n applyExpandedDirs(dirs)\n }\n\n const toggleExpandedDir = (path: string) => {\n const next = new Set(expandedDirs)\n if (next.has(path)) {\n next.delete(path)\n } else {\n next.add(path)\n }\n handleExpandedChange(next)\n }\n\n const handleTreePathChange = useEffectEvent((previousPath: string, nextPath?: string) => {\n setSelectedPath((current) => {\n if (!current) {\n return current\n }\n if (current === previousPath || current.startsWith(`${previousPath}/`)) {\n if (!nextPath) {\n return undefined\n }\n return current === previousPath\n ? nextPath\n : `${nextPath}${current.slice(previousPath.length)}`\n }\n return current\n })\n\n const nextExpanded = new Set<string>()\n for (const path of expandedDirs) {\n if (path === previousPath || path.startsWith(`${previousPath}/`)) {\n if (nextPath) {\n nextExpanded.add(\n path === previousPath ? nextPath : `${nextPath}${path.slice(previousPath.length)}`,\n )\n }\n continue\n }\n nextExpanded.add(path)\n }\n handleExpandedChange(nextExpanded)\n })\n\n const {\n data: rootEntries,\n isLoading: rootLoading,\n error: rootError,\n } = useQuery({\n queryKey: [\"file-tree\", sessionId, rootPath],\n queryFn: () => sessionsApi.listDir(sessionId!, rootPath),\n enabled: !!sessionId,\n refetchInterval: isStreaming ? 60_000 : false,\n })\n\n const handleOpenFile = useEffectEvent(async (path: string, name: string) => {\n if (!sessionId) return\n const currentSessionId = sessionId\n setOpeningFilePath(path)\n setSelectedPath(path)\n try {\n if (onOpenFile) {\n await onOpenFile(path, name)\n } else if (enableEditor) {\n const content = await apiFetchText(\n `/api/sessions/${encodeURIComponent(sessionId)}/files/${encodeURIComponent(path)}`,\n )\n void content\n alert(\"enableEditor 需在宿主应用中提供 onOpenFile\")\n } else {\n await openSessionFileInPreview(sessionId, path, name, pushArtifact, () => {\n return checkActiveSession ? useSessionStore.getState().activeSessionId === currentSessionId : true\n })\n }\n } finally {\n setOpeningFilePath((current) => (current === path ? null : current))\n }\n })\n\n const handleSelect = (path: string) => {\n setSelectedPath(path)\n }\n\n if (!sessionId) {\n return <EmptyState title=\"暂无活跃会话\" description=\"选择或创建会话后查看工作区文件\" />\n }\n\n if (rootLoading) {\n return (\n <div className=\"flex items-center gap-2 px-3 py-4 text-sm text-[hsl(var(--muted-foreground))]\">\n <Loader2 size={14} className=\"animate-spin\" />\n <span>加载中...</span>\n </div>\n )\n }\n\n if (rootError) {\n return (\n <EmptyState\n title=\"文件树加载失败\"\n description={rootError instanceof Error ? rootError.message : \"加载失败\"}\n />\n )\n }\n\n if (!rootEntries || rootEntries.length === 0) {\n return <EmptyState title=\"当前工作区为空\" description=\"会话产生文件后会显示在这里\" />\n }\n\n return (\n <AIFileTree\n expanded={expandedDirs}\n onExpandedChange={handleExpandedChange}\n selectedPath={selectedPath}\n onSelect={handleSelect}\n className=\"border-none bg-transparent\"\n >\n {rootEntries.map((entry) =>\n entry.is_dir ? (\n <FolderNode\n key={entry.path}\n entry={entry}\n expandedDirs={expandedDirs}\n isStreaming={isStreaming}\n onOpenFile={handleOpenFile}\n onSelectPath={handleSelect}\n onToggleDir={toggleExpandedDir}\n onTreePathChange={handleTreePathChange}\n openingFilePath={openingFilePath}\n selectedPath={selectedPath}\n sessionId={sessionId}\n readOnly={readOnly}\n onShareFile={onShareFile}\n allowDelete={allowDelete}\n />\n ) : (\n <FileNode\n key={entry.path}\n entry={entry}\n onOpenFile={handleOpenFile}\n onSelectPath={handleSelect}\n onTreePathChange={handleTreePathChange}\n openingFilePath={openingFilePath}\n selectedPath={selectedPath}\n sessionId={sessionId}\n readOnly={readOnly}\n onShareFile={onShareFile}\n allowDelete={allowDelete}\n />\n ),\n )}\n </AIFileTree>\n )\n}\n\nfunction FolderNode({\n entry,\n expandedDirs,\n isStreaming,\n openingFilePath,\n onOpenFile,\n onSelectPath,\n onToggleDir,\n onTreePathChange,\n selectedPath,\n sessionId,\n readOnly,\n onShareFile,\n allowDelete,\n}: {\n entry: FileEntry\n expandedDirs: Set<string>\n isStreaming: boolean\n openingFilePath: string | null\n onOpenFile: (path: string, name: string) => Promise<void>\n onSelectPath: (path: string) => void\n onToggleDir: (path: string) => void\n onTreePathChange: (previousPath: string, nextPath?: string) => void\n selectedPath?: string\n sessionId: string\n readOnly: boolean\n onShareFile?: (path: string, name: string) => Promise<void>\n allowDelete: boolean\n}) {\n const queryClient = useQueryClient()\n const isExpanded = expandedDirs.has(entry.path)\n const isSelected = selectedPath === entry.path\n const renameInputRef = useRef<HTMLInputElement>(null)\n const [isRenaming, setIsRenaming] = useState(false)\n const [renamingValue, setRenamingValue] = useState(entry.name)\n const [activeAction, setActiveAction] = useState<\"copy\" | \"delete\" | \"rename\" | \"share\" | null>(null)\n\n const downloadUrl = sessionsApi.getDownloadDirUrl(sessionId, entry.path)\n\n useEffect(() => {\n if (!isRenaming) setRenamingValue(entry.name)\n }, [entry.name, isRenaming])\n\n useEffect(() => {\n if (!isRenaming) return\n renameInputRef.current?.focus()\n renameInputRef.current?.select()\n }, [isRenaming])\n\n const finishRename = useEffectEvent(async () => {\n const nextName = renamingValue.trim()\n if (!nextName || nextName === entry.name) {\n setIsRenaming(false)\n setRenamingValue(entry.name)\n return\n }\n setActiveAction(\"rename\")\n try {\n const result = await sessionsApi.renameFile(sessionId, entry.path, nextName)\n onTreePathChange(entry.path, result.path)\n setIsRenaming(false)\n await queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n } catch (error) {\n alert(getErrorMessage(error, \"重命名失败\"))\n renameInputRef.current?.focus()\n renameInputRef.current?.select()\n } finally {\n setActiveAction(null)\n }\n })\n\n const cancelRename = () => {\n setIsRenaming(false)\n setRenamingValue(entry.name)\n }\n\n const handleCopy = async () => {\n setActiveAction(\"copy\")\n try {\n await sessionsApi.copyFile(sessionId, entry.path)\n await queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n } catch (error) {\n alert(getErrorMessage(error, \"复制目录失败\"))\n } finally {\n setActiveAction(null)\n }\n }\n\n const handleDelete = async () => {\n if (!window.confirm(`确认删除目录\"${entry.name}\"吗?`)) {\n return\n }\n setActiveAction(\"delete\")\n try {\n await sessionsApi.deleteFile(sessionId, entry.path)\n onTreePathChange(entry.path)\n await queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n } catch (error) {\n alert(getErrorMessage(error, \"删除目录失败\"))\n } finally {\n setActiveAction(null)\n }\n }\n\n return (\n <Collapsible open={isExpanded} onOpenChange={() => onToggleDir(entry.path)}>\n <div>\n <div className={cn(TREE_ROW_CLASS, isSelected && \"bg-muted\")}>\n <CollapsibleTrigger asChild>\n <button\n type=\"button\"\n className=\"flex shrink-0 cursor-pointer items-center rounded border-none bg-transparent p-0\"\n title={isExpanded ? \"收起目录\" : \"展开目录\"}\n >\n <ChevronRight\n className={cn(\n \"size-4 shrink-0 text-[hsl(var(--muted-foreground))] transition-transform\",\n isExpanded && \"rotate-90\",\n )}\n />\n </button>\n </CollapsibleTrigger>\n {isRenaming ? (\n <>\n <FileTreeIcon>{getFolderIcon()}</FileTreeIcon>\n <input\n ref={renameInputRef}\n value={renamingValue}\n className=\"h-6 min-w-0 flex-1 rounded border border-[hsl(var(--border))] bg-background px-2 text-xs outline-none ring-offset-background focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))]\"\n disabled={activeAction === \"rename\"}\n onBlur={() => void finishRename()}\n onChange={(event) => setRenamingValue(event.target.value)}\n onClick={(event) => event.stopPropagation()}\n onKeyDown={(event) => {\n event.stopPropagation()\n if (event.key === \"Enter\") {\n event.preventDefault()\n void finishRename()\n } else if (event.key === \"Escape\") {\n event.preventDefault()\n cancelRename()\n }\n }}\n />\n </>\n ) : (\n <button\n type=\"button\"\n className=\"flex min-w-0 flex-1 cursor-pointer items-center gap-1 border-none bg-transparent p-0 text-left\"\n onClick={() => {\n onToggleDir(entry.path)\n onSelectPath(entry.path)\n }}\n >\n <FileTreeIcon>{getFolderIcon()}</FileTreeIcon>\n <FileTreeName className=\"min-w-0 flex-1\">{entry.name}</FileTreeName>\n </button>\n )}\n {!readOnly ? <FileTreeActions className=\"ml-auto hidden shrink-0 group-hover:flex\">\n <TreeActionButton\n onClick={() => {\n const anchor = document.createElement(\"a\")\n anchor.href = downloadUrl\n anchor.download = `${entry.name}.zip`\n anchor.click()\n }}\n title=\"下载目录\"\n >\n <Download size={12} />\n </TreeActionButton>\n <TreeActionButton\n disabled={activeAction !== null}\n onClick={() => {\n onSelectPath(entry.path)\n setRenamingValue(entry.name)\n setIsRenaming(true)\n }}\n title=\"重命名\"\n >\n {activeAction === \"rename\" ? <Loader2 size={12} className=\"animate-spin\" /> : <Pencil size={12} />}\n </TreeActionButton>\n <TreeActionButton\n disabled={activeAction !== null}\n onClick={() => void handleCopy()}\n title=\"复制目录\"\n >\n {activeAction === \"copy\" ? <Loader2 size={12} className=\"animate-spin\" /> : <Copy size={12} />}\n </TreeActionButton>\n <TreeActionButton\n disabled={activeAction !== null || !onShareFile}\n onClick={async () => {\n if (!onShareFile) return\n setActiveAction(\"share\")\n try {\n await onShareFile(entry.path, entry.name)\n await queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n } catch (error) {\n alert(getErrorMessage(error, \"共享失败\"))\n } finally {\n setActiveAction(null)\n }\n }}\n title=\"共享到 .share\"\n >\n {activeAction === \"share\" ? <Loader2 size={12} className=\"animate-spin\" /> : <Link2 size={12} />}\n </TreeActionButton>\n <TreeActionButton\n disabled={activeAction !== null}\n onClick={() => void handleDelete()}\n title=\"删除目录\"\n >\n {activeAction === \"delete\" ? <Loader2 size={12} className=\"animate-spin\" /> : <Trash2 size={12} />}\n </TreeActionButton>\n </FileTreeActions> : allowDelete ? (\n <FileTreeActions className=\"ml-auto hidden shrink-0 group-hover:flex\">\n <TreeActionButton\n disabled={activeAction !== null}\n onClick={() => void handleDelete()}\n title=\"删除目录\"\n >\n {activeAction === \"delete\" ? <Loader2 size={12} className=\"animate-spin\" /> : <Trash2 size={12} />}\n </TreeActionButton>\n </FileTreeActions>\n ) : null}\n </div>\n <CollapsibleContent>\n <div className=\"ml-4 border-l pl-2\">\n <LazyDirChildren\n dirPath={entry.path}\n expandedDirs={expandedDirs}\n isStreaming={isStreaming}\n onOpenFile={onOpenFile}\n onSelectPath={onSelectPath}\n onToggleDir={onToggleDir}\n onTreePathChange={onTreePathChange}\n openingFilePath={openingFilePath}\n selectedPath={selectedPath}\n sessionId={sessionId}\n readOnly={readOnly}\n onShareFile={onShareFile}\n allowDelete={allowDelete}\n />\n </div>\n </CollapsibleContent>\n </div>\n </Collapsible>\n )\n}\n\nfunction FileNode({\n entry,\n onOpenFile,\n onSelectPath,\n onTreePathChange,\n openingFilePath,\n selectedPath,\n sessionId,\n readOnly,\n onShareFile,\n allowDelete,\n}: {\n entry: FileEntry\n onOpenFile: (path: string, name: string) => Promise<void>\n onSelectPath: (path: string) => void\n onTreePathChange: (previousPath: string, nextPath?: string) => void\n openingFilePath: string | null\n selectedPath?: string\n sessionId: string\n readOnly: boolean\n onShareFile?: (path: string, name: string) => Promise<void>\n allowDelete: boolean\n}) {\n const downloadUrl = getAuthedUrl(`/api/sessions/${sessionId}/files/${encodeURIComponent(entry.path)}`)\n const isOpening = openingFilePath === entry.path\n const isSelected = selectedPath === entry.path\n const queryClient = useQueryClient()\n const renameInputRef = useRef<HTMLInputElement>(null)\n const [isRenaming, setIsRenaming] = useState(false)\n const [renamingValue, setRenamingValue] = useState(entry.name)\n const [activeAction, setActiveAction] = useState<\"copy\" | \"delete\" | \"rename\" | \"share\" | null>(null)\n\n useEffect(() => {\n if (!isRenaming) {\n setRenamingValue(entry.name)\n }\n }, [entry.name, isRenaming])\n\n useEffect(() => {\n if (!isRenaming) {\n return\n }\n renameInputRef.current?.focus()\n renameInputRef.current?.select()\n }, [isRenaming])\n\n const finishRename = useEffectEvent(async () => {\n const nextName = renamingValue.trim()\n if (!nextName || nextName === entry.name) {\n setIsRenaming(false)\n setRenamingValue(entry.name)\n return\n }\n\n setActiveAction(\"rename\")\n try {\n const result = await sessionsApi.renameFile(sessionId, entry.path, nextName)\n onTreePathChange(entry.path, result.path)\n setIsRenaming(false)\n await queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n } catch (error) {\n alert(getErrorMessage(error, \"重命名失败\"))\n renameInputRef.current?.focus()\n renameInputRef.current?.select()\n } finally {\n setActiveAction(null)\n }\n })\n\n const cancelRename = () => {\n setIsRenaming(false)\n setRenamingValue(entry.name)\n }\n\n const handleCopy = async () => {\n setActiveAction(\"copy\")\n try {\n await sessionsApi.copyFile(sessionId, entry.path)\n await queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n } catch (error) {\n alert(getErrorMessage(error, \"复制文件失败\"))\n } finally {\n setActiveAction(null)\n }\n }\n\n const handleDelete = async () => {\n if (!window.confirm(`确认删除\"${entry.name}\"吗?`)) {\n return\n }\n setActiveAction(\"delete\")\n try {\n await sessionsApi.deleteFile(sessionId, entry.path)\n onTreePathChange(entry.path)\n await queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n } catch (error) {\n alert(getErrorMessage(error, \"删除文件失败\"))\n } finally {\n setActiveAction(null)\n }\n }\n\n return (\n <div className={cn(TREE_ROW_CLASS, isSelected && \"bg-muted\")}>\n <span className=\"size-4 shrink-0\" />\n <FileTreeIcon>{getFileIcon(entry.name)}</FileTreeIcon>\n {isRenaming ? (\n <input\n ref={renameInputRef}\n value={renamingValue}\n className=\"h-6 min-w-0 flex-1 rounded border border-[hsl(var(--border))] bg-background px-2 text-xs outline-none ring-offset-background focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))]\"\n disabled={activeAction === \"rename\"}\n onBlur={() => void finishRename()}\n onChange={(event) => setRenamingValue(event.target.value)}\n onClick={(event) => event.stopPropagation()}\n onKeyDown={(event) => {\n event.stopPropagation()\n if (event.key === \"Enter\") {\n event.preventDefault()\n void finishRename()\n } else if (event.key === \"Escape\") {\n event.preventDefault()\n cancelRename()\n }\n }}\n />\n ) : (\n <button\n type=\"button\"\n className=\"flex min-w-0 flex-1 cursor-pointer items-center border-none bg-transparent p-0 text-left\"\n onClick={() => {\n onSelectPath(entry.path)\n void onOpenFile(entry.path, entry.name)\n }}\n >\n <FileTreeName className=\"min-w-0 flex-1\">{entry.name}</FileTreeName>\n <FileTagList tags={entry.tags} />\n </button>\n )}\n {isOpening ? (\n <Loader2 size={12} className=\"ml-auto shrink-0 animate-spin text-[hsl(var(--muted-foreground))]\" />\n ) : !readOnly ? (\n <FileTreeActions className=\"ml-auto hidden shrink-0 group-hover:flex\">\n <TreeActionButton\n onClick={() => {\n const anchor = document.createElement(\"a\")\n anchor.href = downloadUrl\n anchor.download = entry.name\n anchor.click()\n }}\n title=\"下载文件\"\n >\n <Download size={12} />\n </TreeActionButton>\n <TreeActionButton\n disabled={activeAction !== null}\n onClick={() => {\n onSelectPath(entry.path)\n setRenamingValue(entry.name)\n setIsRenaming(true)\n }}\n title=\"重命名\"\n >\n {activeAction === \"rename\" ? (\n <Loader2 size={12} className=\"animate-spin\" />\n ) : (\n <Pencil size={12} />\n )}\n </TreeActionButton>\n <TreeActionButton\n disabled={activeAction !== null}\n onClick={() => void handleCopy()}\n title=\"复制文件\"\n >\n {activeAction === \"copy\" ? <Loader2 size={12} className=\"animate-spin\" /> : <Copy size={12} />}\n </TreeActionButton>\n <TreeActionButton\n disabled={activeAction !== null || !onShareFile}\n onClick={async () => {\n if (!onShareFile) return\n setActiveAction(\"share\")\n try {\n await onShareFile(entry.path, entry.name)\n await queryClient.invalidateQueries({ queryKey: [\"file-tree\", sessionId] })\n } catch (error) {\n alert(getErrorMessage(error, \"共享失败\"))\n } finally {\n setActiveAction(null)\n }\n }}\n title=\"共享到 .share\"\n >\n {activeAction === \"share\" ? <Loader2 size={12} className=\"animate-spin\" /> : <Link2 size={12} />}\n </TreeActionButton>\n <TreeActionButton\n disabled={activeAction !== null}\n onClick={() => void handleDelete()}\n title=\"删除文件\"\n >\n {activeAction === \"delete\" ? (\n <Loader2 size={12} className=\"animate-spin\" />\n ) : (\n <Trash2 size={12} />\n )}\n </TreeActionButton>\n </FileTreeActions>\n ) : allowDelete ? (\n <FileTreeActions className=\"ml-auto hidden shrink-0 group-hover:flex\">\n <TreeActionButton\n disabled={activeAction !== null}\n onClick={() => void handleDelete()}\n title=\"删除文件\"\n >\n {activeAction === \"delete\" ? <Loader2 size={12} className=\"animate-spin\" /> : <Trash2 size={12} />}\n </TreeActionButton>\n </FileTreeActions>\n ) : null}\n </div>\n )\n}\n\nfunction LazyDirChildren({\n dirPath,\n expandedDirs,\n isStreaming,\n onOpenFile,\n onSelectPath,\n onToggleDir,\n onTreePathChange,\n openingFilePath,\n selectedPath,\n sessionId,\n readOnly,\n onShareFile,\n allowDelete,\n}: {\n dirPath: string\n expandedDirs: Set<string>\n isStreaming: boolean\n onOpenFile: (path: string, name: string) => Promise<void>\n onSelectPath: (path: string) => void\n onToggleDir: (path: string) => void\n onTreePathChange: (previousPath: string, nextPath?: string) => void\n openingFilePath: string | null\n selectedPath?: string\n sessionId: string\n readOnly: boolean\n onShareFile?: (path: string, name: string) => Promise<void>\n allowDelete: boolean\n}) {\n const {\n data: entries,\n isLoading,\n error,\n } = useQuery({\n queryKey: [\"file-tree\", sessionId, dirPath],\n queryFn: () => sessionsApi.listDir(sessionId, dirPath),\n refetchInterval: isStreaming ? 60_000 : false,\n })\n\n if (isLoading) {\n return (\n <div className=\"flex items-center gap-2 px-2 py-1 text-xs text-[hsl(var(--muted-foreground))]\">\n <Loader2 size={12} className=\"animate-spin\" />\n <span>加载中...</span>\n </div>\n )\n }\n if (error) {\n return (\n <div className=\"px-2 py-1 text-xs text-[hsl(var(--muted-foreground))]\">\n {error instanceof Error ? error.message : \"加载失败\"}\n </div>\n )\n }\n if (!entries || entries.length === 0) {\n return <div className=\"px-2 py-1 text-xs text-[hsl(var(--muted-foreground))]\">空目录</div>\n }\n\n return (\n <>\n {entries.map((child) =>\n child.is_dir ? (\n <FolderNode\n key={child.path}\n entry={child}\n expandedDirs={expandedDirs}\n isStreaming={isStreaming}\n onOpenFile={onOpenFile}\n onSelectPath={onSelectPath}\n onToggleDir={onToggleDir}\n onTreePathChange={onTreePathChange}\n openingFilePath={openingFilePath}\n selectedPath={selectedPath}\n sessionId={sessionId}\n readOnly={readOnly}\n onShareFile={onShareFile}\n allowDelete={allowDelete}\n />\n ) : (\n <FileNode\n key={child.path}\n entry={child}\n onOpenFile={onOpenFile}\n onSelectPath={onSelectPath}\n onTreePathChange={onTreePathChange}\n openingFilePath={openingFilePath}\n selectedPath={selectedPath}\n sessionId={sessionId}\n readOnly={readOnly}\n onShareFile={onShareFile}\n allowDelete={allowDelete}\n />\n ),\n )}\n </>\n )\n}\n\nfunction FileTagList({ tags }: { tags?: string[] }) {\n if (!tags || tags.length === 0) return null\n return (\n <span className=\"ml-2 flex min-w-0 shrink-0 items-center gap-1\">\n {tags.map((tag) => (\n <span\n key={tag}\n className=\"max-w-20 truncate rounded border border-[hsl(var(--border))] bg-[hsl(var(--muted))] px-1.5 py-0.5 text-[10px] leading-none text-[hsl(var(--muted-foreground))]\"\n title={tag}\n >\n {tag}\n </span>\n ))}\n </span>\n )\n}\n\nfunction TreeActionButton({\n children,\n disabled = false,\n onClick,\n title,\n}: {\n children: ReactNode\n disabled?: boolean\n onClick: () => void\n title: string\n}) {\n return (\n <button\n type=\"button\"\n disabled={disabled}\n onClick={onClick}\n title={title}\n className=\"flex items-center rounded p-1 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--muted-foreground))/10] hover:text-[hsl(var(--foreground))] disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {children}\n </button>\n )\n}\n\nfunction EmptyState({ title, description }: { title: string; description: string }) {\n return (\n <div className=\"flex h-full min-h-[12rem] flex-col items-center justify-center gap-3 px-6 text-center\">\n <div className=\"flex h-10 w-10 items-center justify-center text-[hsl(var(--muted-foreground))]\">\n {getFolderIcon()}\n </div>\n <div className=\"space-y-1\">\n <div className=\"text-sm font-medium text-[hsl(var(--foreground))]\">{title}</div>\n <div className=\"text-sm text-[hsl(var(--muted-foreground))]\">{description}</div>\n </div>\n </div>\n )\n}\n\nfunction getFileIcon(fileName: string): ReactNode {\n const ext = fileName.split(\".\").pop()?.toLowerCase() ?? \"\"\n const src = FILE_ICON_ASSETS[ext] ?? GENERIC_FILE_ICON_ASSET\n return <FileTypeIcon src={src} alt={`${ext || \"file\"} 文件`} />\n}\n\nfunction getFolderIcon(): ReactNode {\n return <FileTypeIcon src={FOLDER_ICON_ASSET} alt=\"文件夹\" />\n}\n\nfunction FileTypeIcon({ src, alt }: { src: string; alt: string }) {\n return (\n <img\n src={src}\n alt={alt}\n className=\"size-4 shrink-0 object-contain\"\n draggable={false}\n loading=\"lazy\"\n />\n )\n}\n\nfunction getErrorMessage(error: unknown, fallback: string): string {\n if (error instanceof Error && error.message) {\n return error.message\n }\n return fallback\n}\n","import type { PreviewTarget } from \"../stores/ui-store\"\nimport { resolveSessionFilePreviewTarget } from \"./session-file-preview\"\n\nexport async function openSessionFileInPreview(\n sessionId: string,\n filePath: string,\n fileName: string,\n pushArtifact: (target: PreviewTarget) => void,\n shouldOpen: () => boolean = () => true,\n): Promise<void> {\n try {\n const target = await resolveSessionFilePreviewTarget(sessionId, filePath, fileName)\n if (!shouldOpen()) {\n return\n }\n pushArtifact(target)\n } catch {\n /* file may not exist */\n }\n}\n","\"use client\";\n\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"../ui/collapsible\"\nimport { cn } from \"../../lib/utils\"\nimport {\n ChevronRightIcon,\n FileIcon,\n FolderIcon,\n FolderOpenIcon,\n} from \"lucide-react\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n} from \"react\";\n\ninterface FileTreeContextType {\n expandedPaths: Set<string>;\n togglePath: (path: string) => void;\n selectedPath?: string;\n onSelect?: (path: string) => void;\n}\n\n// Default noop for context default value\n// oxlint-disable-next-line eslint(no-empty-function)\nconst noop = () => {};\n\nconst FileTreeContext = createContext<FileTreeContextType>({\n // oxlint-disable-next-line eslint-plugin-unicorn(no-new-builtin)\n expandedPaths: new Set(),\n togglePath: noop,\n});\n\nexport type FileTreeProps = Omit<HTMLAttributes<HTMLDivElement>, \"onSelect\"> & {\n expanded?: Set<string>;\n defaultExpanded?: Set<string>;\n selectedPath?: string;\n onSelect?: (path: string) => void;\n onExpandedChange?: (expanded: Set<string>) => void;\n};\n\nexport const FileTree = ({\n expanded: controlledExpanded,\n defaultExpanded = new Set(),\n selectedPath,\n onSelect,\n onExpandedChange,\n className,\n children,\n ...props\n}: FileTreeProps) => {\n const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);\n const expandedPaths = controlledExpanded ?? internalExpanded;\n\n const togglePath = useCallback(\n (path: string) => {\n const newExpanded = new Set(expandedPaths);\n if (newExpanded.has(path)) {\n newExpanded.delete(path);\n } else {\n newExpanded.add(path);\n }\n setInternalExpanded(newExpanded);\n onExpandedChange?.(newExpanded);\n },\n [expandedPaths, onExpandedChange]\n );\n\n const contextValue = useMemo(\n () => ({ expandedPaths, onSelect, selectedPath, togglePath }),\n [expandedPaths, onSelect, selectedPath, togglePath]\n );\n\n return (\n <FileTreeContext.Provider value={contextValue}>\n <div\n className={cn(\n \"rounded-lg border bg-background font-mono text-sm\",\n className\n )}\n role=\"tree\"\n {...props}\n >\n <div className=\"p-2\">{children}</div>\n </div>\n </FileTreeContext.Provider>\n );\n};\n\nexport type FileTreeIconProps = HTMLAttributes<HTMLSpanElement>;\n\nexport const FileTreeIcon = ({\n className,\n children,\n ...props\n}: FileTreeIconProps) => (\n <span className={cn(\"shrink-0\", className)} {...props}>\n {children}\n </span>\n);\n\nexport type FileTreeNameProps = HTMLAttributes<HTMLSpanElement>;\n\nexport const FileTreeName = ({\n className,\n children,\n ...props\n}: FileTreeNameProps) => (\n <span className={cn(\"truncate\", className)} {...props}>\n {children}\n </span>\n);\n\ninterface FileTreeFolderContextType {\n path: string;\n name: string;\n isExpanded: boolean;\n}\n\nconst FileTreeFolderContext = createContext<FileTreeFolderContextType>({\n isExpanded: false,\n name: \"\",\n path: \"\",\n});\n\nexport type FileTreeFolderProps = HTMLAttributes<HTMLDivElement> & {\n path: string;\n name: string;\n};\n\nexport const FileTreeFolder = ({\n path,\n name,\n className,\n children,\n ...props\n}: FileTreeFolderProps) => {\n const { expandedPaths, togglePath, selectedPath, onSelect } =\n useContext(FileTreeContext);\n const isExpanded = expandedPaths.has(path);\n const isSelected = selectedPath === path;\n\n const handleOpenChange = useCallback(() => {\n togglePath(path);\n }, [togglePath, path]);\n\n const handleSelect = useCallback(() => {\n togglePath(path);\n onSelect?.(path);\n }, [togglePath, onSelect, path]);\n\n const folderContextValue = useMemo(\n () => ({ isExpanded, name, path }),\n [isExpanded, name, path]\n );\n\n return (\n <FileTreeFolderContext.Provider value={folderContextValue}>\n <Collapsible onOpenChange={handleOpenChange} open={isExpanded}>\n <div\n className={cn(\"\", className)}\n {...props}\n >\n <div\n className={cn(\n \"flex w-full items-center gap-1 rounded px-2 py-1 text-left transition-colors hover:bg-muted/50\",\n isSelected && \"bg-muted\"\n )}\n >\n <CollapsibleTrigger asChild>\n <button\n className=\"flex shrink-0 cursor-pointer items-center border-none bg-transparent p-0\"\n type=\"button\"\n >\n <ChevronRightIcon\n className={cn(\n \"size-4 shrink-0 text-muted-foreground transition-transform\",\n isExpanded && \"rotate-90\"\n )}\n />\n </button>\n </CollapsibleTrigger>\n <button\n className=\"flex min-w-0 flex-1 cursor-pointer items-center gap-1 border-none bg-transparent p-0 text-left\"\n onClick={handleSelect}\n type=\"button\"\n >\n <FileTreeIcon>\n {isExpanded ? (\n <FolderOpenIcon className=\"size-4 text-primary\" />\n ) : (\n <FolderIcon className=\"size-4 text-primary\" />\n )}\n </FileTreeIcon>\n <FileTreeName>{name}</FileTreeName>\n </button>\n </div>\n <CollapsibleContent>\n <div className=\"ml-4 border-l pl-2\">{children}</div>\n </CollapsibleContent>\n </div>\n </Collapsible>\n </FileTreeFolderContext.Provider>\n );\n};\n\ninterface FileTreeFileContextType {\n path: string;\n name: string;\n}\n\nconst FileTreeFileContext = createContext<FileTreeFileContextType>({\n name: \"\",\n path: \"\",\n});\n\nexport type FileTreeFileProps = HTMLAttributes<HTMLButtonElement> & {\n path: string;\n name: string;\n icon?: ReactNode;\n};\n\nexport const FileTreeFile = ({\n path,\n name,\n icon,\n className,\n children,\n ...props\n}: FileTreeFileProps) => {\n const { selectedPath, onSelect } = useContext(FileTreeContext);\n const isSelected = selectedPath === path;\n\n const handleClick = useCallback(() => {\n onSelect?.(path);\n }, [onSelect, path]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n onSelect?.(path);\n }\n },\n [onSelect, path]\n );\n\n const fileContextValue = useMemo(() => ({ name, path }), [name, path]);\n\n return (\n <FileTreeFileContext.Provider value={fileContextValue}>\n <button\n type=\"button\"\n className={cn(\n \"flex w-full cursor-pointer items-center gap-1 rounded border-none bg-transparent px-2 py-1 text-left text-inherit transition-colors hover:bg-muted/50\",\n isSelected && \"bg-muted\",\n className\n )}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n {...props}\n >\n {children ?? (\n <>\n {/* Spacer for alignment */}\n <span className=\"size-4 shrink-0\" />\n <FileTreeIcon>\n {icon ?? <FileIcon className=\"size-4 text-muted-foreground\" />}\n </FileTreeIcon>\n <FileTreeName>{name}</FileTreeName>\n </>\n )}\n </button>\n </FileTreeFileContext.Provider>\n );\n};\n\nexport type FileTreeActionsProps = HTMLAttributes<HTMLDivElement>;\n\nconst stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();\n\nexport const FileTreeActions = ({\n className,\n children,\n ...props\n}: FileTreeActionsProps) => (\n <div\n className={cn(\"ml-auto flex items-center gap-1\", className)}\n onClick={stopPropagation}\n onKeyDown={stopPropagation}\n {...props}\n >\n {children}\n </div>\n);\n","export const FILE_ICON_ASSETS: Record<string, string> = {\n \"7z\": new URL(\"../../assets/file-icons/archive/7z.png\", import.meta.url).href,\n \"bz2\": new URL(\"../../assets/file-icons/archive/bz2.png\", import.meta.url).href,\n \"dmg\": new URL(\"../../assets/file-icons/archive/dmg.png\", import.meta.url).href,\n \"gz\": new URL(\"../../assets/file-icons/archive/gz.png\", import.meta.url).href,\n \"iso\": new URL(\"../../assets/file-icons/archive/iso.png\", import.meta.url).href,\n \"pkg\": new URL(\"../../assets/file-icons/archive/pkg.png\", import.meta.url).href,\n \"rar\": new URL(\"../../assets/file-icons/archive/rar.png\", import.meta.url).href,\n \"tar\": new URL(\"../../assets/file-icons/archive/tar.png\", import.meta.url).href,\n \"tgz\": new URL(\"../../assets/file-icons/archive/tgz.png\", import.meta.url).href,\n \"xz\": new URL(\"../../assets/file-icons/archive/xz.png\", import.meta.url).href,\n \"zip\": new URL(\"../../assets/file-icons/archive/zip.png\", import.meta.url).href,\n \"aac\": new URL(\"../../assets/file-icons/audio/aac.png\", import.meta.url).href,\n \"aiff\": new URL(\"../../assets/file-icons/audio/aiff.png\", import.meta.url).href,\n \"flac\": new URL(\"../../assets/file-icons/audio/flac.png\", import.meta.url).href,\n \"m4a\": new URL(\"../../assets/file-icons/audio/m4a.png\", import.meta.url).href,\n \"mid\": new URL(\"../../assets/file-icons/audio/mid.png\", import.meta.url).href,\n \"mp3\": new URL(\"../../assets/file-icons/audio/mp3.png\", import.meta.url).href,\n \"ogg\": new URL(\"../../assets/file-icons/audio/ogg.png\", import.meta.url).href,\n \"wav\": new URL(\"../../assets/file-icons/audio/wav.png\", import.meta.url).href,\n \"c\": new URL(\"../../assets/file-icons/code/c.png\", import.meta.url).href,\n \"cpp\": new URL(\"../../assets/file-icons/code/cpp.png\", import.meta.url).href,\n \"cs\": new URL(\"../../assets/file-icons/code/cs.png\", import.meta.url).href,\n \"css\": new URL(\"../../assets/file-icons/code/css.png\", import.meta.url).href,\n \"go\": new URL(\"../../assets/file-icons/code/go.png\", import.meta.url).href,\n \"h\": new URL(\"../../assets/file-icons/code/h.png\", import.meta.url).href,\n \"hpp\": new URL(\"../../assets/file-icons/code/hpp.png\", import.meta.url).href,\n \"html\": new URL(\"../../assets/file-icons/code/html.png\", import.meta.url).href,\n \"java\": new URL(\"../../assets/file-icons/code/java.png\", import.meta.url).href,\n \"js\": new URL(\"../../assets/file-icons/code/js.png\", import.meta.url).href,\n \"json\": new URL(\"../../assets/file-icons/code/json.png\", import.meta.url).href,\n \"jsx\": new URL(\"../../assets/file-icons/code/jsx.png\", import.meta.url).href,\n \"kt\": new URL(\"../../assets/file-icons/code/kt.png\", import.meta.url).href,\n \"lock\": new URL(\"../../assets/file-icons/code/lock.png\", import.meta.url).href,\n \"php\": new URL(\"../../assets/file-icons/code/php.png\", import.meta.url).href,\n \"py\": new URL(\"../../assets/file-icons/code/py.png\", import.meta.url).href,\n \"rb\": new URL(\"../../assets/file-icons/code/rb.png\", import.meta.url).href,\n \"rs\": new URL(\"../../assets/file-icons/code/rs.png\", import.meta.url).href,\n \"scss\": new URL(\"../../assets/file-icons/code/scss.png\", import.meta.url).href,\n \"sh\": new URL(\"../../assets/file-icons/code/sh.png\", import.meta.url).href,\n \"sql\": new URL(\"../../assets/file-icons/code/sql.png\", import.meta.url).href,\n \"svelte\": new URL(\"../../assets/file-icons/code/svelte.png\", import.meta.url).href,\n \"swift\": new URL(\"../../assets/file-icons/code/swift.png\", import.meta.url).href,\n \"toml\": new URL(\"../../assets/file-icons/code/toml.png\", import.meta.url).href,\n \"ts\": new URL(\"../../assets/file-icons/code/ts.png\", import.meta.url).href,\n \"tsx\": new URL(\"../../assets/file-icons/code/tsx.png\", import.meta.url).href,\n \"vue\": new URL(\"../../assets/file-icons/code/vue.png\", import.meta.url).href,\n \"xml\": new URL(\"../../assets/file-icons/code/xml.png\", import.meta.url).href,\n \"yaml\": new URL(\"../../assets/file-icons/code/yaml.png\", import.meta.url).href,\n \"yml\": new URL(\"../../assets/file-icons/code/yml.png\", import.meta.url).href,\n \"zsh\": new URL(\"../../assets/file-icons/code/zsh.png\", import.meta.url).href,\n \"conf\": new URL(\"../../assets/file-icons/config/conf.png\", import.meta.url).href,\n \"env\": new URL(\"../../assets/file-icons/config/env.png\", import.meta.url).href,\n \"ini\": new URL(\"../../assets/file-icons/config/ini.png\", import.meta.url).href,\n \"db\": new URL(\"../../assets/file-icons/data/db.png\", import.meta.url).href,\n \"jsonl\": new URL(\"../../assets/file-icons/data/jsonl.png\", import.meta.url).href,\n \"ndjson\": new URL(\"../../assets/file-icons/data/ndjson.png\", import.meta.url).href,\n \"parquet\": new URL(\"../../assets/file-icons/data/parquet.png\", import.meta.url).href,\n \"plist\": new URL(\"../../assets/file-icons/data/plist.png\", import.meta.url).href,\n \"sqlite\": new URL(\"../../assets/file-icons/data/sqlite.png\", import.meta.url).href,\n \"blend\": new URL(\"../../assets/file-icons/design/blend.png\", import.meta.url).href,\n \"fig\": new URL(\"../../assets/file-icons/design/fig.png\", import.meta.url).href,\n \"sketch\": new URL(\"../../assets/file-icons/design/sketch.png\", import.meta.url).href,\n \"xd\": new URL(\"../../assets/file-icons/design/xd.png\", import.meta.url).href,\n \"epub\": new URL(\"../../assets/file-icons/document/epub.png\", import.meta.url).href,\n \"key\": new URL(\"../../assets/file-icons/document/key.png\", import.meta.url).href,\n \"log\": new URL(\"../../assets/file-icons/document/log.png\", import.meta.url).href,\n \"markdown\": new URL(\"../../assets/file-icons/document/markdown.png\", import.meta.url).href,\n \"md\": new URL(\"../../assets/file-icons/document/md.png\", import.meta.url).href,\n \"numbers\": new URL(\"../../assets/file-icons/document/numbers.png\", import.meta.url).href,\n \"pages\": new URL(\"../../assets/file-icons/document/pages.png\", import.meta.url).href,\n \"pdf\": new URL(\"../../assets/file-icons/document/pdf.png\", import.meta.url).href,\n \"tex\": new URL(\"../../assets/file-icons/document/tex.png\", import.meta.url).href,\n \"txt\": new URL(\"../../assets/file-icons/document/txt.png\", import.meta.url).href,\n \"otf\": new URL(\"../../assets/file-icons/font/otf.png\", import.meta.url).href,\n \"ttf\": new URL(\"../../assets/file-icons/font/ttf.png\", import.meta.url).href,\n \"woff\": new URL(\"../../assets/file-icons/font/woff.png\", import.meta.url).href,\n \"woff2\": new URL(\"../../assets/file-icons/font/woff2.png\", import.meta.url).href,\n \"ai\": new URL(\"../../assets/file-icons/image/ai.png\", import.meta.url).href,\n \"avif\": new URL(\"../../assets/file-icons/image/avif.png\", import.meta.url).href,\n \"bmp\": new URL(\"../../assets/file-icons/image/bmp.png\", import.meta.url).href,\n \"gif\": new URL(\"../../assets/file-icons/image/gif.png\", import.meta.url).href,\n \"heic\": new URL(\"../../assets/file-icons/image/heic.png\", import.meta.url).href,\n \"heif\": new URL(\"../../assets/file-icons/image/heif.png\", import.meta.url).href,\n \"ico\": new URL(\"../../assets/file-icons/image/ico.png\", import.meta.url).href,\n \"jpeg\": new URL(\"../../assets/file-icons/image/jpeg.png\", import.meta.url).href,\n \"jpg\": new URL(\"../../assets/file-icons/image/jpg.png\", import.meta.url).href,\n \"png\": new URL(\"../../assets/file-icons/image/png.png\", import.meta.url).href,\n \"psd\": new URL(\"../../assets/file-icons/image/psd.png\", import.meta.url).href,\n \"svg\": new URL(\"../../assets/file-icons/image/svg.png\", import.meta.url).href,\n \"tif\": new URL(\"../../assets/file-icons/image/tif.png\", import.meta.url).href,\n \"tiff\": new URL(\"../../assets/file-icons/image/tiff.png\", import.meta.url).href,\n \"webp\": new URL(\"../../assets/file-icons/image/webp.png\", import.meta.url).href,\n \"csv\": new URL(\"../../assets/file-icons/office/csv.png\", import.meta.url).href,\n \"doc\": new URL(\"../../assets/file-icons/office/doc.png\", import.meta.url).href,\n \"docx\": new URL(\"../../assets/file-icons/office/docx.png\", import.meta.url).href,\n \"ppt\": new URL(\"../../assets/file-icons/office/ppt.png\", import.meta.url).href,\n \"pptx\": new URL(\"../../assets/file-icons/office/pptx.png\", import.meta.url).href,\n \"rtf\": new URL(\"../../assets/file-icons/office/rtf.png\", import.meta.url).href,\n \"tsv\": new URL(\"../../assets/file-icons/office/tsv.png\", import.meta.url).href,\n \"xls\": new URL(\"../../assets/file-icons/office/xls.png\", import.meta.url).href,\n \"xlsx\": new URL(\"../../assets/file-icons/office/xlsx.png\", import.meta.url).href,\n \"odg\": new URL(\"../../assets/file-icons/open-document/odg.png\", import.meta.url).href,\n \"odp\": new URL(\"../../assets/file-icons/open-document/odp.png\", import.meta.url).href,\n \"ods\": new URL(\"../../assets/file-icons/open-document/ods.png\", import.meta.url).href,\n \"odt\": new URL(\"../../assets/file-icons/open-document/odt.png\", import.meta.url).href,\n \"avi\": new URL(\"../../assets/file-icons/video/avi.png\", import.meta.url).href,\n \"flv\": new URL(\"../../assets/file-icons/video/flv.png\", import.meta.url).href,\n \"m4v\": new URL(\"../../assets/file-icons/video/m4v.png\", import.meta.url).href,\n \"mkv\": new URL(\"../../assets/file-icons/video/mkv.png\", import.meta.url).href,\n \"mov\": new URL(\"../../assets/file-icons/video/mov.png\", import.meta.url).href,\n \"mp4\": new URL(\"../../assets/file-icons/video/mp4.png\", import.meta.url).href,\n \"webm\": new URL(\"../../assets/file-icons/video/webm.png\", import.meta.url).href,\n \"wmv\": new URL(\"../../assets/file-icons/video/wmv.png\", import.meta.url).href,\n}\n\nexport const FOLDER_ICON_ASSET = new URL(\"../../assets/file-icons/folder.png\", import.meta.url).href\nexport const GENERIC_FILE_ICON_ASSET = new URL(\"../../assets/file-icons/generic-file.png\", import.meta.url).href\n"],"mappings":"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","names":["useQueryClient","Loader2","useEffect","useMemo","useRef","useState","useState","Fragment","jsx","jsxs","FileTree","useState","jsx","jsxs","useState","useQueryClient","useRef","useMemo","title","useEffect","Loader2","FileTree"]}
|