dsh-comfyui 0.3.0-beta.0
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/LICENSE +21 -0
- package/README.md +160 -0
- package/README.zh.md +160 -0
- package/client/client.js +3089 -0
- package/client/client.js.map +1 -0
- package/cordis.patch.yml +4 -0
- package/lib/analyze.d.ts +61 -0
- package/lib/analyze.js +96 -0
- package/lib/comfyui.d.ts +195 -0
- package/lib/comfyui.js +392 -0
- package/lib/config.d.ts +71 -0
- package/lib/config.js +28 -0
- package/lib/convert.d.ts +35 -0
- package/lib/convert.js +289 -0
- package/lib/host-hint.d.ts +29 -0
- package/lib/host-hint.js +73 -0
- package/lib/http.d.ts +15 -0
- package/lib/http.js +41 -0
- package/lib/index.d.ts +24 -0
- package/lib/index.js +344 -0
- package/lib/params.d.ts +63 -0
- package/lib/params.js +537 -0
- package/lib/progress.d.ts +27 -0
- package/lib/progress.js +98 -0
- package/lib/proxy.d.ts +13 -0
- package/lib/proxy.js +89 -0
- package/lib/queue.d.ts +50 -0
- package/lib/queue.js +103 -0
- package/lib/routes.d.ts +13 -0
- package/lib/routes.js +800 -0
- package/lib/skill.d.ts +12 -0
- package/lib/skill.js +72 -0
- package/lib/store.d.ts +120 -0
- package/lib/store.js +193 -0
- package/lib/templates.d.ts +36 -0
- package/lib/templates.js +84 -0
- package/lib/tools.d.ts +165 -0
- package/lib/tools.js +493 -0
- package/package.json +80 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","names":["h","useState","h","useState","h","useSyncExternalStore","h","useState","useRef","h","useCallback","h"],"sources":["../src/client/i18n.ts","../src/client/lightbox.tsx","../src/client/card.tsx","../src/client/api.ts","../src/client/settings.tsx","../src/client/panel-store.ts","../src/client/trigger.tsx","../src/client/panel.tsx","../src/client/styles.ts","../src/client/index.ts"],"sourcesContent":["/** zh/en dictionaries for dsh-comfyui UI (settings page, tool card, panel). */\nexport const zh = {\n // settings page\n settingsTitle: 'ComfyUI',\n settingsDesc: '连接你的 ComfyUI 服务器,让 Agent 直接生成与处理图像、视频。',\n baseUrl: '服务器地址',\n baseUrlHint: 'ComfyUI 的 HTTP 地址(默认 http://127.0.0.1:8188)。',\n apiKeyEnv: 'API Key 环境变量名',\n apiKeyEnvHint: '凭据存储或环境变量中的密钥名(默认 COMFYUI_API_KEY),远程服务通常需要。',\n hasApiKey: '已配置 API Key',\n noApiKey: '未配置 API Key(本地服务通常不需要)',\n save: '保存',\n saved: '已保存',\n saveFailed: '保存失败',\n test: '测试连接',\n testing: '正在测试…',\n testOk: '连接成功 · ComfyUI {version} · {ms} ms',\n testFail: '连接失败:{message}',\n configNotWritable: '设置服务不可用,请通过 cordis.yml 修改配置。',\n mediaHost: '媒体访问地址',\n mediaHostHint: '生成图片/媒体在聊天中使用的完整地址(如 http://192.168.1.5:3080)。留空时自动使用浏览器访问本服务器的地址;内网或反向代理下若图片不显示,请在此填写你访问本页面所用的地址。',\n language: '界面语言',\n languageHint: '切换插件界面语言(中文 / English)。切换后页面会自动刷新。',\n // tool card\n cardGenerating: 'ComfyUI 生成中…',\n cardBackground: '后台任务',\n cardBackgroundDone: '已完成',\n cardPrompt: '任务 ID',\n cardElapsed: '耗时',\n cardMedia: '结果',\n cardEmpty: '无媒体输出',\n cardFailed: '执行失败',\n cardInterrupted: '已中断',\n cardCollect: '使用 job_output 收集后台任务结果',\n cardLoadFailed: '加载失败,点下方下载',\n cardDownload: '下载',\n cardWorkflow: '工作流',\n cardMode: '模式',\n cardListed: '已列出 {runs} 个运行工作流,{graphs} 个图工作流',\n // panel shell\n panelTitle: 'ComfyUI 面板',\n close: '关闭',\n lbPrev: '上一张',\n lbNext: '下一张',\n tabWorkflows: '工作流',\n tabAssets: '资产',\n tabQueue: '队列',\n error: '出错',\n refresh: '刷新',\n ours: '本插件',\n // workflows tab\n wfAdd: '新建工作流',\n wfName: '名称',\n wfDesc: '概述',\n wfDescPlaceholder: '告诉 Agent 这个工作流做什么',\n wfNameCopyHint: '点击复制工作流名称',\n wfNameCopied: '已复制工作流名称',\n wfParams: '可调参数',\n wfTags: '标签',\n wfTagAll: '全部',\n wfTagAdd: '自定义标签,回车添加',\n wfTagRemove: '点击移除标签',\n wfParamsEmpty: '未定义参数。点击\"识别参数\"自动提取提示词/分辨率/步数/种子,或\"高级参数\"手动指定任意节点输入。',\n wfParamsDrop: '拖拽/点击/粘贴上传',\n wfPasteHint: '悬停此处后按 Ctrl+V 粘贴剪贴板里的图片/文件',\n wfUploadSection: '加载区',\n wfUploadHint: '点击大图选择图像,或粘贴/上传新图像;选中后图生图默认使用该图像',\n wfUploadZone: '拖拽 / 点击 / 粘贴上传到 ComfyUI input 目录',\n wfUploaded: '已上传',\n wfCopyName: '复制文件名',\n wfLoadArea: '加载区',\n wfLoadHint: '点击选择图像(加载区选中的图像将作为图生图的默认源图)',\n wfLoadEmpty: '未选择图像,点击选择',\n wfLoadPicked: '已加载',\n wfTabAll: '全部',\n wfTabImported: '已导入',\n wfTabGenerated: '已生成',\n wfTypeAll: '全部类型',\n wfUploadedToast: '文件已上传',\n wfPickerUpload: '粘贴 / 点击上传',\n wfLoadNoFiles: '没有可用的图像',\n wfParamsUploading: '上传中…',\n uploadKind_image: '图片',\n uploadKind_video: '视频',\n uploadKind_audio: '音频',\n wfMediaClear: '清空',\n wfMediaEmpty: '文件名(留空=移除该参考位)',\n wfRefSlot: '参考',\n wfParamsRecognize: '识别参数',\n wfParamsRecognizing: '识别中…',\n wfParamsRecognizeFailed: '识别失败:无法连接 ComfyUI 或工作流无效',\n wfParamsAdd: '高级参数',\n wfParamAdd: '添加',\n wfParamLabel: '名称',\n wfParamCustomLabel: '自定义名称',\n wfParamCustomHint: '仅用于展示与 Agent 描述,传参键由系统自动生成;留空使用默认',\n wfParamDefault: '默认值',\n wfParamRandom: '随机',\n wfParamDelete: '删除',\n wfParamNode: '节点',\n wfParamInput: '输入',\n wfJson: '工作流 JSON(ComfyUI UI 导出的 API 格式)',\n wfSave: '保存',\n wfSaveRun: '保存并运行',\n wfCancel: '取消',\n wfEdit: '编辑',\n wfRun: '运行',\n wfDelete: '删除',\n wfQueued: '已入队:',\n wfJsonError: '工作流 JSON 解析失败',\n wfUpdated: '更新于',\n wfEmpty: '没有检测到任何工作流,请通过新建、导入或提取来创建执行流程。',\n wfLibrarySection: 'API 工作流',\n wfRefresh: '刷新',\n wfImportFile: '导入文件',\n wfComfyuiSection: 'ComfyUI 工作流',\n wfComfyuiHint: '面板自动检测 ComfyUI 中保存的工作流。\\n注:非 API 流程,无法直接执行,需经过提取转化为 API 工作流,或自行导入 API 工作流即可执行。',\n wfComfyuiEmpty: 'ComfyUI 端没有检测到保存的工作流',\n wfExtracted: '已提取',\n wfNotExtracted: '未提取',\n wfView: '查看',\n wfExtract: '提取',\n wfExtractedNotice: '已提取并加入插件库',\n wfExtractTitle: '提取执行流',\n wfExtractModeAll: '整体提取',\n wfExtractModeAllHint: '所有分量合成一个执行流(运行时全部执行)',\n wfExtractModeSplit: '按分量提取',\n wfExtractModeSplitHint: '每个独立流程一个执行流(推荐)',\n wfExtractModeMain: '只提取主流程',\n wfExtractModeMainHint: '只提取最大分量(通常是当前测试区块)',\n wfExtractRun: '提取',\n wfExtractEmpty: '图里没有可提取的分量',\n wfComponents: '分量',\n wfComponentLabel: '分量',\n wfNodes: '节点',\n wfBypassed: '已绕过节点',\n wfIsolated: '悬空节点',\n wfViewBack: '返回',\n wfViewNodes: '节点清单',\n wfViewJson: 'JSON 预览',\n wfViewEmpty: '图中没有可执行的节点',\n // assets tab\n assetAll: '全部工作流',\n assetBack: '返回',\n assetEmpty: '还没有生成记录。运行工作流后,结果会出现在这里。',\n assetGone: '源文件已被 ComfyUI 清理',\n // queue tab (task center)\n queueEmpty: '当前没有任务',\n queueError: '无法读取队列(ComfyUI 未运行?)',\n jobFilterLabel: '历史',\n jobFilterAll: '全部',\n jobFilterPending: '待生成',\n jobFilterInProgress: '生成中',\n jobFilterCompleted: '已完成',\n jobFilterFailed: '失败',\n jobFilterCancelled: '已取消',\n jobActive: '进行中',\n jobDelete: '删除',\n jobInterrupt: '中断',\n jobRerun: '重跑',\n jobViewAssets: '查看资产',\n jobMore: '更多操作',\n jobClearQueue: '清空队列',\n jobClearHistory: '清空历史',\n jobFree: '释放内存',\n jobDuration: '耗时',\n jobOurs: '本插件',\n}\n\nexport const en = {\n // settings page\n settingsTitle: 'ComfyUI',\n settingsDesc: 'Connect your ComfyUI server so the agent can generate and process images and videos directly.',\n baseUrl: 'Server URL',\n baseUrlHint: 'ComfyUI HTTP address (default http://127.0.0.1:8188).',\n apiKeyEnv: 'API key env var',\n apiKeyEnvHint: 'Credential-store or environment variable name (default COMFYUI_API_KEY); usually needed for remote servers.',\n hasApiKey: 'API key configured',\n noApiKey: 'No API key configured (usually not needed for local servers)',\n save: 'Save',\n saved: 'Saved',\n saveFailed: 'Save failed',\n test: 'Test connection',\n testing: 'Testing…',\n testOk: 'Connected · ComfyUI {version} · {ms} ms',\n testFail: 'Connection failed: {message}',\n configNotWritable: 'Settings service unavailable — edit cordis.yml instead.',\n mediaHost: 'Media base URL',\n mediaHostHint: 'Absolute base URL used for generated media in chat (e.g. http://192.168.1.5:3080). Leave empty to auto-detect the address your browser uses to reach this server; fill it in when images do not load over LAN or a reverse proxy.',\n language: 'Language',\n languageHint: 'Switch the plugin UI language (中文 / English). The page reloads after switching.',\n // tool card\n cardGenerating: 'ComfyUI generating…',\n cardBackground: 'Background job',\n cardBackgroundDone: 'Completed',\n cardPrompt: 'Prompt ID',\n cardElapsed: 'Elapsed',\n cardMedia: 'Results',\n cardEmpty: 'No media outputs',\n cardFailed: 'Execution failed',\n cardInterrupted: 'Interrupted',\n cardCollect: 'Collect the background job result with job_output',\n cardLoadFailed: 'failed to load, use the download link below',\n cardDownload: 'Download',\n cardWorkflow: 'Workflow',\n cardMode: 'Mode',\n cardListed: 'Listed {runs} runnable workflows, {graphs} graph workflows',\n // panel shell\n panelTitle: 'ComfyUI Panel',\n close: 'Close',\n lbPrev: 'Previous image',\n lbNext: 'Next image',\n tabWorkflows: 'Workflows',\n tabAssets: 'Assets',\n tabQueue: 'Queue',\n error: 'Error',\n refresh: 'Refresh',\n ours: 'ours',\n // workflows tab\n wfAdd: 'New workflow',\n wfName: 'Name',\n wfDesc: 'Overview',\n wfDescPlaceholder: 'Tells the agent what this workflow does',\n wfNameCopyHint: 'Click to copy the workflow name',\n wfNameCopied: 'Workflow name copied',\n wfParams: 'Parameters',\n wfTags: 'Tags',\n wfTagAll: 'All',\n wfTagAdd: 'Custom tag, press Enter to add',\n wfTagRemove: 'Click to remove tag',\n wfParamsEmpty: 'No parameters yet. Click \"Detect\" to auto-extract prompt / resolution / steps / seed, or \"Advanced\" to expose any node input manually.',\n wfParamsDrop: 'Drop / Click / Paste to upload',\n wfPasteHint: 'Hover here and press Ctrl+V to paste an image/file',\n wfUploadSection: 'Load area',\n wfUploadHint: 'Click the preview to pick an image, or paste/upload a new one; the selection becomes the default source for image-to-image',\n wfUploadZone: 'Drag / Click / Paste to upload into the ComfyUI input dir',\n wfUploaded: 'Uploaded',\n wfCopyName: 'Copy file name',\n wfLoadArea: 'Load area',\n wfLoadHint: 'Click to pick an image (the selection becomes the default source for image-to-image)',\n wfLoadEmpty: 'No image selected — click to pick',\n wfLoadPicked: 'Loaded',\n wfTabAll: 'All',\n wfTabImported: 'Imported',\n wfTabGenerated: 'Generated',\n wfTypeAll: 'All types',\n wfUploadedToast: 'File uploaded',\n wfPickerUpload: 'Paste / Click to upload',\n wfLoadNoFiles: 'No images available',\n wfParamsUploading: 'Uploading…',\n uploadKind_image: 'image',\n uploadKind_video: 'video',\n uploadKind_audio: 'audio',\n wfMediaClear: 'Clear',\n wfMediaEmpty: 'filename (empty = drop this slot)',\n wfRefSlot: 'Ref ',\n wfParamsRecognize: 'Detect',\n wfParamsRecognizing: 'Detecting…',\n wfParamsRecognizeFailed: 'Detection failed: ComfyUI unreachable or invalid workflow',\n wfParamsAdd: 'Advanced',\n wfParamAdd: 'Add',\n wfParamLabel: 'Name',\n wfParamCustomLabel: 'Custom name',\n wfParamCustomHint: 'Shown to the user and the agent only; the parameter key is generated automatically. Leave empty for the default',\n wfParamDefault: 'Default',\n wfParamRandom: 'Random',\n wfParamDelete: 'Delete',\n wfParamNode: 'Node',\n wfParamInput: 'Input',\n wfJson: 'Workflow JSON (API format exported from the ComfyUI UI)',\n wfSave: 'Save',\n wfSaveRun: 'Save & Run',\n wfCancel: 'Cancel',\n wfEdit: 'Edit',\n wfRun: 'Run',\n wfDelete: 'Delete',\n wfQueued: 'Queued: ',\n wfJsonError: 'Workflow JSON could not be parsed',\n wfUpdated: 'updated',\n wfEmpty: 'No workflows detected — create one via New, Import, or Extract.',\n wfLibrarySection: 'API workflows',\n wfRefresh: 'Refresh',\n wfImportFile: 'Import file',\n wfComfyuiSection: 'ComfyUI workflows',\n wfComfyuiHint: 'Auto-detects workflows saved in ComfyUI.\\nNote: these are UI graphs, not directly runnable — extract them into API workflows, or import an API workflow instead.',\n wfComfyuiEmpty: 'No workflows detected on the ComfyUI server',\n wfExtracted: 'extracted',\n wfNotExtracted: 'not extracted',\n wfView: 'View',\n wfExtract: 'Extract',\n wfExtractedNotice: 'extracted into the library',\n wfExtractTitle: 'Extract runnable workflows',\n wfExtractModeAll: 'All as one',\n wfExtractModeAllHint: 'Merge every component into one runnable workflow (everything executes)',\n wfExtractModeSplit: 'Per component',\n wfExtractModeSplitHint: 'One runnable workflow per independent flow (recommended)',\n wfExtractModeMain: 'Main flow only',\n wfExtractModeMainHint: 'Only the largest component (usually the flow under test)',\n wfExtractRun: 'Extract',\n wfExtractEmpty: 'No extractable components in this graph',\n wfComponents: 'components',\n wfComponentLabel: 'Component',\n wfNodes: 'nodes',\n wfBypassed: 'bypassed nodes',\n wfIsolated: 'dangling nodes',\n wfViewBack: 'Back',\n wfViewNodes: 'Nodes',\n wfViewJson: 'JSON preview',\n wfViewEmpty: 'No executable nodes in this graph',\n // assets tab\n assetAll: 'All workflows',\n assetBack: 'Back',\n assetEmpty: 'Nothing generated yet. Results appear here after workflows run.',\n assetGone: 'Source file evicted by ComfyUI',\n // queue tab (task center)\n queueEmpty: 'No tasks right now',\n queueError: 'Cannot read the queue (ComfyUI not running?)',\n jobFilterLabel: 'History',\n jobFilterAll: 'All',\n jobFilterPending: 'Pending',\n jobFilterInProgress: 'Running',\n jobFilterCompleted: 'Completed',\n jobFilterFailed: 'Failed',\n jobFilterCancelled: 'Cancelled',\n jobActive: 'Active',\n jobDelete: 'Delete',\n jobInterrupt: 'Interrupt',\n jobRerun: 'Rerun',\n jobViewAssets: 'View assets',\n jobMore: 'More actions',\n jobClearQueue: 'Clear queue',\n jobClearHistory: 'Clear history',\n jobFree: 'Free memory',\n jobDuration: 'Took',\n jobOurs: 'ours',\n}\n\nexport type Lang = 'zh' | 'en'\nexport const LANGS: readonly Lang[] = ['zh', 'en']\nconst LANG_KEY = 'dsh-comfyui.lang'\n\n/** Current plugin UI language, read from localStorage (default zh). */\nexport function getLang(): Lang {\n try {\n return localStorage.getItem(LANG_KEY) === 'en' ? 'en' : 'zh'\n } catch {\n return 'zh'\n }\n}\n\n/** Persist the plugin UI language choice. */\nexport function setLang(lang: Lang): void {\n try {\n localStorage.setItem(LANG_KEY, lang)\n } catch {\n // storage unavailable (e.g. private mode): the choice just does not persist\n }\n}\n\nconst DICTS: Record<Lang, Record<string, string>> = { zh, en }\n\n/** Build a plugin-local translator for one language. Resolves {name}\n * placeholders from the first rest argument (same contract as the DSH\n * locale bind), falling back to the key itself when untranslated. */\nexport function makeT(lang: Lang): (key: string, ...rest: unknown[]) => string {\n const dict = DICTS[lang]\n return (key, ...rest) => {\n const template = dict[key] ?? key\n const params = (rest[0] ?? {}) as Record<string, unknown>\n if (params !== null && typeof params === 'object') {\n return template.replace(/\\{(\\w+)\\}/g, (match, name: string) => {\n const value = params[name]\n return value === undefined ? match : String(value)\n })\n }\n return template\n }\n}\n","/**\n * Shared lightbox: opens a generated image full-screen with prev/next\n * navigation, keyboard support, and a download pill. Used by both the panel\n * (assets/queue previews) and the tool card (result images).\n */\nimport { createElement as h, useEffect } from 'react'\n\nexport interface LightboxProps {\n t: (key: string, ...rest: unknown[]) => string\n images: string[]\n /** Per-image media kind, parallel to `images`; omitted defaults to image. */\n kinds?: Array<'image' | 'video' | 'audio' | 'other'>\n index: number\n onClose: () => void\n onIndex: (index: number) => void\n}\n\n/** Full-screen media overlay with prev/next navigation. */\nexport function Lightbox({ t, images, kinds, index, onClose, onIndex }: LightboxProps): ReturnType<typeof h> | null {\n const count = images.length\n useEffect(() => {\n const onKey = (event: KeyboardEvent): void => {\n if (event.key === 'Escape') onClose()\n else if (event.key === 'ArrowLeft') onIndex((index - 1 + count) % count)\n else if (event.key === 'ArrowRight') onIndex((index + 1) % count)\n }\n document.addEventListener('keydown', onKey)\n return () => document.removeEventListener('keydown', onKey)\n }, [index, count, onClose, onIndex])\n const src = images[index]\n if (src === undefined) return null\n const kind = kinds?.[index] ?? 'image'\n const media = kind === 'video'\n ? h('video', { className: 'dsc-lightbox-media', src, controls: true, autoPlay: true })\n : kind === 'audio'\n ? h('audio', { className: 'dsc-lightbox-media', src, controls: true, autoPlay: true })\n : kind === 'image'\n ? h('img', { className: 'dsc-lightbox-img', src, alt: '' })\n : h('div', { className: 'dsc-lightbox-media' }, src)\n return h('div', { className: 'dsc-lightbox', onClick: onClose },\n h('div', { className: 'dsc-lightbox-body', onClick: (event: { stopPropagation: () => void }) => event.stopPropagation() },\n h('button', {\n className: 'dsc-lightbox-close',\n 'aria-label': t('close'),\n onClick: (event: { stopPropagation: () => void }) => { event.stopPropagation(); onClose() },\n }, '✕'),\n count > 1\n ? h('button', {\n className: 'dsc-lightbox-nav dsc-lightbox-nav--prev',\n 'aria-label': t('lbPrev'),\n onClick: (event: { stopPropagation: () => void }) => { event.stopPropagation(); onIndex((index - 1 + count) % count) },\n }, '‹')\n : null,\n media,\n h('div', { className: 'dsc-lightbox-meta' },\n h('span', null, `${index + 1} / ${count}`),\n h('a', { className: 'dsc-lightbox-download', href: src, download: '', target: '_blank', rel: 'noreferrer' }, t('cardDownload')),\n ),\n count > 1\n ? h('button', {\n className: 'dsc-lightbox-nav dsc-lightbox-nav--next',\n 'aria-label': t('lbNext'),\n onClick: (event: { stopPropagation: () => void }) => { event.stopPropagation(); onIndex((index + 1) % count) },\n }, '›')\n : null,\n ),\n )\n}\n","/**\n * Tool cards for comfyui_run and comfyui_workflow (tool.call.toolview, keys\n * 'comfyui_run' / 'comfyui_workflow'). A pure function of the frozen tool-call\n * block: running calls show a generating state, settled calls render the\n * presentationMeta payload (media wall with size labels, click-to-zoom\n * lightbox, status) that the host threaded into the session log.\n */\nimport { createElement as h, useEffect, useState } from 'react'\nimport { Lightbox } from './lightbox.js'\n\ninterface MediaItem {\n filename: string\n subfolder: string\n type: string\n node: string\n index: number\n kind: 'image' | 'video' | 'audio' | 'other'\n url: string\n}\n\ninterface SyncMeta {\n kind: 'sync'\n promptId: string\n status: 'completed' | 'interrupted'\n elapsedMs: number\n media: MediaItem[]\n summary: string\n}\n\ninterface BackgroundMeta {\n kind: 'background'\n jobId: string\n promptId: string\n label: string\n}\n\ntype RunMeta = SyncMeta | BackgroundMeta\n\n/** Settled tool-result node (structural slice of the wire ToolCallBlock). */\ninterface ToolResultNode {\n kind: 'tool-result'\n call?: { name: string; argsRaw: string } | null\n isError?: boolean\n error?: { name?: string; code?: string }\n meta?: unknown\n}\n\n/** Running tool-call node (structural slice). */\ninterface RunningToolCall {\n callId: string\n name: string\n argsRaw: string\n}\n\ntype Block = ToolResultNode | RunningToolCall\n\n/** Discriminate the settled result node from a running call. */\nfunction isResultNode(block: Block): block is ToolResultNode {\n return (block as ToolResultNode).kind === 'tool-result'\n}\n\nexport interface ComfyUICardProps {\n t: (key: string, ...rest: unknown[]) => string\n block: Block\n}\n\nfunction parseArgs(raw: string): Record<string, unknown> {\n try {\n const parsed = JSON.parse(raw)\n return typeof parsed === 'object' && parsed !== null ? parsed as Record<string, unknown> : {}\n } catch {\n return {}\n }\n}\n\nfunction argsSummary(args: Record<string, unknown>): string {\n const parts: string[] = []\n if (typeof args.template === 'string') parts.push(`template=${args.template}`)\n if (args.mode !== undefined && args.mode !== 'sync') parts.push(`mode=${String(args.mode)}`)\n if (parts.length === 0) parts.push('custom workflow')\n return parts.join(' · ')\n}\n\nfunction aspectLabel(width: number, height: number): string {\n const gcd = (a: number, b: number): number => (b === 0 ? a : gcd(b, a % b))\n const g = gcd(width, height)\n const rw = width / g\n const rh = height / g\n return rw <= 32 && rh <= 32 ? `${rw}:${rh}` : ''\n}\n\nfunction MediaItem({ item, t, onOpen }: {\n item: MediaItem\n t: ComfyUICardProps['t']\n onOpen: () => void\n}): ReturnType<typeof h> {\n const [size, setSize] = useState<{ width: number; height: number } | null>(null)\n const [failed, setFailed] = useState(false)\n const media = item.kind === 'video'\n ? h('video', { src: item.url, controls: true, preload: 'metadata' })\n : item.kind === 'audio'\n ? h('audio', { src: item.url, controls: true, preload: 'metadata' })\n : item.kind === 'image'\n ? failed\n ? h('span', { className: 'dsc-media-other' }, `${item.filename}(${t('cardLoadFailed')})`)\n : h('img', {\n src: item.url,\n alt: item.filename,\n loading: 'lazy',\n className: 'dsc-media-img dsc-media-img--clickable',\n onClick: onOpen,\n onLoad: (event: { target: { naturalWidth?: number; naturalHeight?: number } }) => {\n const width = event.target.naturalWidth\n const height = event.target.naturalHeight\n if (typeof width === 'number' && typeof height === 'number' && width > 0 && height > 0) {\n setSize({ width, height })\n }\n },\n onError: () => setFailed(true),\n })\n : h('span', { className: 'dsc-media-other' }, item.filename)\n const ratio = size === null ? null : aspectLabel(size.width, size.height)\n return h('div', { className: 'dsc-media' },\n media,\n h('div', { className: 'dsc-media-meta' },\n size !== null\n ? h('span', { className: 'dsc-media-size' }, `${size.width}×${size.height}${ratio !== '' ? ` · ${ratio}` : ''}`)\n : null,\n h('a', { href: item.url, download: item.filename, target: '_blank', rel: 'noreferrer' }, t('cardDownload')),\n ),\n )\n}\n\nfunction ResultCard({ title, result, t }: {\n title: string\n result: SyncMeta\n t: ComfyUICardProps['t']\n}): ReturnType<typeof h> {\n const failed = result.status === 'interrupted'\n const [lightbox, setLightbox] = useState<number | null>(null)\n const urls = result.media.map((item) => item.url)\n const kinds = result.media.map((item) => item.kind)\n return h('div', { className: 'dsc-card' },\n h('div', { className: 'dsc-card-head' },\n title !== '' ? h('span', { className: 'dsc-badge' }, title) : null,\n h('span', { className: failed ? 'dsc-badge dsc-badge--err' : 'dsc-badge dsc-badge--ok' },\n failed ? t('cardInterrupted') : result.status),\n h('span', { className: 'dsc-meta' }, `${t('cardPrompt')} ${result.promptId}`),\n h('span', { className: 'dsc-meta' }, `${t('cardElapsed')} ${result.elapsedMs} ms`),\n ),\n h('div', { className: 'dsc-meta' }, result.summary),\n result.media.length > 0\n ? h('div', { className: 'dsc-grid' }, result.media.map((item, index) => h(MediaItem, {\n key: `${item.node}-${item.index}`,\n item,\n t,\n onOpen: () => setLightbox(index),\n })))\n : h('div', { className: 'dsc-meta' }, t('cardEmpty')),\n lightbox !== null\n ? h(Lightbox, { t, images: urls, kinds, index: lightbox, onClose: () => setLightbox(null), onIndex: setLightbox })\n : null,\n )\n}\n\nfunction BackgroundCard({ label, promptId, t }: {\n label: string\n promptId: string\n t: ComfyUICardProps['t']\n}): ReturnType<typeof h> {\n // The tool returns immediately with a background job; this card polls the\n // job's history entry and, once completed, renders the collected media in\n // place (same wall as a sync result).\n const [result, setResult] = useState<{ status: string; media?: MediaItem[]; error?: string } | null>(null)\n const [lightbox, setLightbox] = useState<number | null>(null)\n\n useEffect(() => {\n let stopped = false\n let timer: number | undefined\n const poll = async (): Promise<void> => {\n try {\n const response = await fetch(`/comfyui/jobs/media?promptId=${encodeURIComponent(promptId)}`, { headers: { accept: 'application/json' } })\n const data = (await response.json()) as { ok?: boolean; status?: string; media?: MediaItem[]; error?: string }\n if (stopped) return\n if (data.ok !== true || data.status === undefined) return\n if (data.status === 'completed' || data.status === 'failed') {\n setResult({ status: data.status, media: data.media, error: data.error })\n return\n }\n timer = window.setTimeout(() => { void poll() }, 3_000)\n } catch {\n timer = window.setTimeout(() => { void poll() }, 5_000)\n }\n }\n void poll()\n return () => {\n stopped = true\n if (timer !== undefined) window.clearTimeout(timer)\n }\n }, [promptId])\n\n if (result !== null && (result.status === 'completed' || result.status === 'failed')) {\n const media = result.media ?? []\n const urls = media.map((item) => item.url)\n const kinds = media.map((item) => item.kind)\n return h('div', { className: 'dsc-card' },\n h('div', { className: 'dsc-card-head' },\n h('span', { className: result.status === 'failed' ? 'dsc-badge dsc-badge--err' : 'dsc-badge dsc-badge--ok' },\n result.status === 'failed' ? t('cardFailed') : t('cardBackgroundDone')),\n h('span', { className: 'dsc-meta' }, `${label} · ${promptId}`),\n ),\n result.status === 'failed'\n ? h('div', { className: 'dsc-meta dsc-job-error' }, result.error ?? t('cardFailed'))\n : media.length > 0\n ? h('div', { className: 'dsc-grid' }, media.map((item, index) => h(MediaItem, {\n key: `${item.node}-${item.index}`,\n item,\n t,\n onOpen: () => setLightbox(index),\n })))\n : h('div', { className: 'dsc-meta' }, t('cardEmpty')),\n lightbox !== null\n ? h(Lightbox, { t, images: urls, kinds, index: lightbox, onClose: () => setLightbox(null), onIndex: setLightbox })\n : null,\n )\n }\n\n return h('div', { className: 'dsc-card' },\n h('div', { className: 'dsc-card-head' },\n h('span', { className: 'dsc-badge' }, t('cardBackground')),\n h('span', { className: 'dsc-meta' }, `${label} · ${promptId}`),\n ),\n h('div', { className: 'dsc-meta' }, t('cardCollect')),\n )\n}\n\n/** meta of a comfyui_workflow call (action: run / list / get). */\ntype WorkflowMeta = {\n action: 'run'\n id: string\n workflowName?: string\n result?: SyncMeta\n background?: BackgroundMeta\n} | {\n action: 'list'\n workflows?: unknown[]\n comfyuiWorkflows?: unknown[]\n} | {\n action: 'get'\n id?: string\n name?: string\n}\n\nfunction SettledCard({ block, t }: { block: ToolResultNode; t: ComfyUICardProps['t'] }): ReturnType<typeof h> {\n if (block.isError === true) {\n return h('div', { className: 'dsc-card' },\n h('div', { className: 'dsc-card-head' },\n h('span', { className: 'dsc-badge dsc-badge--err' }, t('cardFailed')),\n ),\n h('div', { className: 'dsc-meta' }, block.error?.name ?? 'error'),\n )\n }\n const meta = block.meta as RunMeta | WorkflowMeta | undefined\n if (meta === undefined || typeof meta !== 'object') {\n return h('div', { className: 'dsc-card' }, h('span', { className: 'dsc-badge' }, block.call?.name ?? 'comfyui'))\n }\n // comfyui_workflow: action-shaped meta.\n if ('action' in meta) {\n if (meta.action === 'run') {\n if (meta.background !== undefined) {\n return h(BackgroundCard, { label: meta.workflowName ?? '', promptId: meta.background.promptId, t })\n }\n if (meta.result !== undefined) {\n return h(ResultCard, { title: meta.workflowName ?? '', result: meta.result, t })\n }\n }\n if (meta.action === 'list') {\n const runs = meta.workflows?.length ?? 0\n const graphs = meta.comfyuiWorkflows?.length ?? 0\n return h('div', { className: 'dsc-card' },\n h('div', { className: 'dsc-card-head' }, h('span', { className: 'dsc-badge' }, 'comfyui_workflow')),\n h('div', { className: 'dsc-meta' }, t('cardListed', { runs, graphs })),\n )\n }\n if (meta.action === 'get') {\n return h('div', { className: 'dsc-card' },\n h('div', { className: 'dsc-card-head' }, h('span', { className: 'dsc-badge' }, 'comfyui_workflow')),\n h('div', { className: 'dsc-meta' }, meta.name ?? meta.id ?? 'get'),\n )\n }\n return h('div', { className: 'dsc-card' }, h('span', { className: 'dsc-badge' }, 'comfyui_workflow'))\n }\n // comfyui_run: kind-shaped meta.\n if (meta.kind === 'background') {\n return h(BackgroundCard, { label: meta.label, promptId: meta.promptId, t })\n }\n return h(ResultCard, { title: '', result: meta, t })\n}\n\n/** The card component: picks running vs settled rendering from the block. */\nexport function ComfyUICard({ t, block }: ComfyUICardProps): ReturnType<typeof h> {\n if (isResultNode(block)) {\n return h(SettledCard, { block, t })\n }\n const args = parseArgs(block.argsRaw)\n return h('div', { className: 'dsc-card' },\n h('div', { className: 'dsc-card-head' },\n h('span', { className: 'dsc-badge' }, t('cardGenerating')),\n h('span', { className: 'dsc-meta' }, `${t('cardWorkflow')} ${argsSummary(args)} · ${t('cardMode')} ${String(args.mode ?? 'sync')}`),\n ),\n )\n}\n","/** Same-origin JSON helpers shared by the settings page and the panel. */\nexport async function getJson<T>(url: string): Promise<T> {\n const response = await fetch(url, { headers: { accept: 'application/json' } })\n if (!response.ok) throw new Error(`HTTP ${response.status}`)\n return (await response.json()) as T\n}\n\nexport async function postJson(url: string, body: unknown): Promise<unknown> {\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n })\n if (!response.ok) {\n const payload = (await response.json().catch(() => ({}))) as { error?: string }\n throw new Error(payload.error ?? `HTTP ${response.status}`)\n }\n return response.json() as Promise<unknown>\n}\n","/**\n * The ComfyUI settings page (settings.section, id 'comfyui'). Reads the\n * redacted host config over /comfyui/config, persists edits through the same\n * route, and probes the server over /comfyui/test.\n */\nimport { createElement as h, useEffect, useState } from 'react'\nimport { getJson, postJson } from './api.ts'\nimport { getLang, setLang, type Lang } from './i18n.ts'\n\nexport interface ComfyUISettingsProps {\n t: (key: string, ...rest: unknown[]) => string\n close: () => void\n}\n\ninterface ConfigView {\n baseUrl: string\n apiKeyEnv: string\n hasApiKey: boolean\n timeoutMs: number\n pollIntervalMs: number\n maxMediaItems: number\n mediaHost: string\n writable: boolean\n}\n\ninterface TestResult {\n ok: boolean\n text: string\n}\n\n/** The ComfyUI settings page component. */\nexport function ComfyUISettings({ t }: ComfyUISettingsProps): ReturnType<typeof h> {\n const [config, setConfig] = useState<ConfigView | null>(null)\n const [baseUrl, setBaseUrl] = useState('')\n const [apiKeyEnv, setApiKeyEnv] = useState('')\n const [mediaHost, setMediaHost] = useState('')\n const [loadError, setLoadError] = useState<string | null>(null)\n const [saving, setSaving] = useState(false)\n const [saveState, setSaveState] = useState<'idle' | 'saved' | 'failed'>('idle')\n const [testing, setTesting] = useState(false)\n const [testResult, setTestResult] = useState<TestResult | null>(null)\n const [lang, setLangState] = useState<Lang>(getLang())\n\n useEffect(() => {\n let cancelled = false\n getJson<ConfigView>('/comfyui/config').then((view) => {\n if (cancelled) return\n setConfig(view)\n setBaseUrl(view.baseUrl)\n setApiKeyEnv(view.apiKeyEnv)\n setMediaHost(view.mediaHost ?? '')\n }).catch((error: unknown) => {\n if (cancelled) return\n setLoadError(error instanceof Error ? error.message : String(error))\n })\n return () => {\n cancelled = true\n }\n }, [])\n\n const save = async (): Promise<void> => {\n setSaving(true)\n setSaveState('idle')\n try {\n const payload = (await postJson('/comfyui/config', { patch: { baseUrl, apiKeyEnv, mediaHost } })) as { config?: ConfigView }\n if (payload.config !== undefined) {\n setConfig(payload.config)\n setBaseUrl(payload.config.baseUrl)\n setApiKeyEnv(payload.config.apiKeyEnv)\n setMediaHost(payload.config.mediaHost ?? '')\n }\n setSaveState('saved')\n } catch (error) {\n setSaveState('failed')\n setTestResult({ ok: false, text: error instanceof Error ? error.message : String(error) })\n } finally {\n setSaving(false)\n }\n }\n\n const test = async (): Promise<void> => {\n setTesting(true)\n setTestResult(null)\n try {\n const payload = (await postJson('/comfyui/test', {})) as { ok: boolean; version?: string; latencyMs?: number; error?: string }\n if (payload.ok === true) {\n setTestResult({ ok: true, text: t('testOk', { version: payload.version ?? 'unknown', ms: payload.latencyMs ?? 0 }) })\n } else {\n setTestResult({ ok: false, text: t('testFail', { message: payload.error ?? 'unknown error' }) })\n }\n } catch (error) {\n setTestResult({ ok: false, text: t('testFail', { message: error instanceof Error ? error.message : String(error) }) })\n } finally {\n setTesting(false)\n }\n }\n\n if (loadError !== null) {\n return h('div', { className: 'dsc-card' },\n h('div', { className: 'dsc-meta' }, `${t('saveFailed')}: ${loadError}`),\n )\n }\n if (config === null) {\n return h('div', { className: 'dsc-card' }, h('div', { className: 'dsc-meta' }, '…'))\n }\n\n return h('div', { className: 'dsc-form' },\n h('div', { className: 'dsc-meta' }, t('settingsDesc')),\n h('div', { className: 'dsc-field' },\n h('label', null, t('language')),\n h('select', {\n className: 'dsc-input',\n value: lang,\n onChange: (event: { target: { value: string } }) => {\n const next: Lang = event.target.value === 'en' ? 'en' : 'zh'\n setLangState(next)\n setLang(next)\n window.location.reload()\n },\n },\n h('option', { value: 'zh' }, '中文'),\n h('option', { value: 'en' }, 'English'),\n ),\n h('div', { className: 'dsc-hint' }, t('languageHint')),\n ),\n h('div', { className: 'dsc-field' },\n h('label', null, t('baseUrl')),\n h('input', {\n value: baseUrl,\n placeholder: 'http://127.0.0.1:8188',\n onChange: (event: { target: { value: string } }) => { setBaseUrl(event.target.value); setSaveState('idle') },\n }),\n h('div', { className: 'dsc-hint' }, t('baseUrlHint')),\n ),\n h('div', { className: 'dsc-field' },\n h('label', null, t('apiKeyEnv')),\n h('input', {\n value: apiKeyEnv,\n placeholder: 'COMFYUI_API_KEY',\n onChange: (event: { target: { value: string } }) => { setApiKeyEnv(event.target.value); setSaveState('idle') },\n }),\n h('div', { className: 'dsc-hint' }, `${t('apiKeyEnvHint')} — ${config.hasApiKey ? t('hasApiKey') : t('noApiKey')}`),\n ),\n h('div', { className: 'dsc-field' },\n h('label', null, t('mediaHost')),\n h('input', {\n value: mediaHost,\n placeholder: 'http://192.168.1.5:3080',\n onChange: (event: { target: { value: string } }) => { setMediaHost(event.target.value); setSaveState('idle') },\n }),\n h('div', { className: 'dsc-hint' }, t('mediaHostHint')),\n ),\n h('div', { className: 'dsc-row' },\n h('button', { className: 'dsc-btn', disabled: saving || !config.writable, onClick: () => void save() }, t('save')),\n h('button', { className: 'dsc-btn', disabled: testing, onClick: () => void test() }, testing ? t('testing') : t('test')),\n saveState === 'saved' ? h('span', { className: 'dsc-note' }, t('saved')) : null,\n saveState === 'failed' ? h('span', { className: 'dsc-note' }, t('saveFailed')) : null,\n ),\n testResult !== null\n ? h('div', { className: testResult.ok ? 'dsc-note' : 'dsc-note', style: testResult.ok ? { color: '#22c55e' } : { color: '#ef4444' } }, testResult.text)\n : null,\n config.writable ? null : h('div', { className: 'dsc-hint' }, t('configNotWritable')),\n )\n}\n","/**\n * Shared open/close/tab state for the ComfyUI panel. The overlay occupant\n * and the session-header trigger are separate registrations in one bundle,\n * so they coordinate through this module-level store plus useSyncExternalStore.\n */\nimport { useSyncExternalStore } from 'react'\n\nconst listeners = new Set<() => void>()\nlet open = false\nlet tab: PanelTab = 'workflows'\nlet assetFilter = ''\n\nfunction emit(): void {\n for (const listener of listeners) listener()\n}\n\nexport type PanelTab = 'workflows' | 'assets' | 'queue'\n\nexport const panelStore = {\n isOpen: () => open,\n toggle: () => {\n open = !open\n emit()\n },\n open: () => {\n if (!open) {\n open = true\n emit()\n }\n },\n close: () => {\n if (open) {\n open = false\n emit()\n }\n },\n getTab: () => tab,\n setTab: (next: PanelTab) => {\n if (tab !== next) {\n tab = next\n emit()\n }\n },\n getAssetFilter: () => assetFilter,\n setAssetFilter: (name: string) => {\n if (assetFilter !== name) {\n assetFilter = name\n emit()\n }\n },\n subscribe(listener: () => void): () => void {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n}\n\n/** React hook reading the panel open state. */\nexport function usePanelOpen(): boolean {\n return useSyncExternalStore(panelStore.subscribe, panelStore.isOpen, panelStore.isOpen)\n}\n\n/** React hook reading the active panel tab. */\nexport function usePanelTab(): PanelTab {\n return useSyncExternalStore(panelStore.subscribe, panelStore.getTab, panelStore.getTab)\n}\n","/**\n * The session-header trigger (conversation.session.header.actions, id\n * 'comfyui'): a labelled button that toggles the ComfyUI panel.\n */\nimport { createElement as h } from 'react'\nimport { panelStore, usePanelOpen } from './panel-store.ts'\n\nexport interface ComfyUITriggerProps {\n t: (key: string, ...rest: unknown[]) => string\n}\n\n/**\n * ComfyUI brand glyph (mono), inlined from @lobehub/icons-static-svg\n * (lobehub.com/icons). currentColor fill keeps it theme-aware.\n */\nexport function ComfyUIIcon(): ReturnType<typeof h> {\n return h('svg', {\n viewBox: '0 0 24 24',\n width: '1em', height: '1em',\n fill: 'currentColor', fillRule: 'evenodd',\n style: { flex: 'none', lineHeight: 1 },\n 'aria-hidden': true,\n }, h('path', { d: 'M5.485 23.76c-.568 0-1.026-.207-1.325-.598-.307-.402-.387-.964-.22-1.54l.672-2.315a.605.605 0 00-.1-.536.622.622 0 00-.494-.243H2.085c-.568 0-1.026-.207-1.325-.598-.307-.403-.387-.964-.22-1.54l2.31-7.917.255-.87c.343-1.18 1.592-2.14 2.786-2.14h2.313c.276 0 .519-.18.595-.442l.764-2.633C9.906 1.208 11.155.249 12.35.249l4.945-.008h3.62c.568 0 1.027.206 1.325.597.307.402.387.964.22 1.54l-1.035 3.566c-.343 1.178-1.593 2.137-2.787 2.137l-4.956.01H11.37a.618.618 0 00-.594.441l-1.928 6.604a.605.605 0 00.1.537c.118.153.3.243.495.243l3.275-.006h3.61c.568 0 1.026.206 1.325.598.307.402.387.964.22 1.54l-1.036 3.565c-.342 1.179-1.592 2.138-2.786 2.138l-4.957.01h-3.61z' }),\n )\n}\n\n/** Header-action button toggling the ComfyUI panel. */\nexport function ComfyUITrigger({ t }: ComfyUITriggerProps): ReturnType<typeof h> {\n const open = usePanelOpen()\n return h('button', {\n className: 'dsc-trigger',\n title: t('panelTitle'),\n 'aria-label': t('panelTitle'),\n 'aria-pressed': open,\n onClick: () => panelStore.toggle(),\n },\n h('span', { className: 'dsc-trigger-glyph' }, h(ComfyUIIcon)),\n h('span', null, t('panelTitle')),\n )\n}\n","/**\n * The ComfyUI panel (shell.overlay, id 'comfyui.panel'): a floating panel\n * with three tabs — workflow library management, generated asset preview,\n * and the live ComfyUI queue. Draggable by its header and resizable via the\n * corner handle; geometry persists in localStorage. Renders null while closed\n * (the overlay layer is click-through, so nothing blocks the app underneath).\n */\nimport { createElement as h, useCallback, useEffect, useRef, useState } from 'react'\nimport { getJson, postJson } from './api.ts'\nimport { panelStore, usePanelOpen, usePanelTab } from './panel-store.ts'\nimport { ComfyUIIcon } from './trigger.tsx'\nimport { Lightbox } from './lightbox.js'\n\n/** Panel geometry: pixel position/size once the user dragged or resized. */\ninterface PanelGeom {\n x?: number\n y?: number\n width?: number\n height?: number\n}\n\nconst GEOM_KEY = 'dsh-comfyui-panel-geom'\n\nfunction loadGeom(): PanelGeom {\n try {\n const raw = localStorage.getItem(GEOM_KEY)\n if (raw === null) return {}\n const parsed = JSON.parse(raw) as Record<string, unknown>\n const geom: PanelGeom = {}\n if (typeof parsed.x === 'number') geom.x = parsed.x\n if (typeof parsed.y === 'number') geom.y = parsed.y\n if (typeof parsed.width === 'number' && parsed.width >= 300) geom.width = parsed.width\n if (typeof parsed.height === 'number' && parsed.height >= 200) geom.height = parsed.height\n return geom\n } catch {\n return {}\n }\n}\n\nfunction saveGeom(geom: PanelGeom): void {\n try {\n localStorage.setItem(GEOM_KEY, JSON.stringify(geom))\n } catch {\n // storage unavailable — geometry just won't persist\n }\n}\n\ninterface PointerEventLike {\n pointerId: number\n clientX: number\n clientY: number\n button: number\n target: EventTarget | null\n currentTarget: EventTarget | null\n}\n\nexport interface ComfyUIPanelProps {\n t: (key: string, ...rest: unknown[]) => string\n}\n\ninterface MediaItem {\n filename: string\n subfolder: string\n type: string\n node: string\n index: number\n kind: 'image' | 'video' | 'other'\n url: string\n}\n\ninterface WorkflowEntry {\n id: string\n name: string\n description: string\n workflow: Record<string, unknown>\n parameters?: WorkflowParameter[]\n tags?: string[]\n updatedAt: string\n}\n\n/** Preset workflow classification tags (users can add custom ones). Stored as\n * plain text, so the tag identity is the label itself. */\nconst PRESET_TAGS = ['图生图', '文生图', '文生视频', '图生视频', '参考生视频', '文生音频', '参考生音频']\n\n/** A workflow saved on the ComfyUI server (userdata/workflows). */\ninterface ComfyUIWorkflowEntry {\n name: string\n size?: number\n modified?: number\n /** Whether at least one runnable API workflow was extracted from this graph. */\n extracted: boolean\n /** Runnable API workflows extracted from this graph. */\n derived: Array<{ libraryId: string; name: string }>\n}\n\n/** One connected component of a ComfyUI-side graph. */\ninterface ComponentInfo {\n index: number\n size: number\n groups: string[]\n nodeTypes: string[]\n}\n\n/** Canvas analysis result for the extract dialog. */\ninterface GraphAnalysis {\n components: ComponentInfo[]\n isolated: Array<{ id: number; type: string }>\n bypassedCount: number\n mode: 'single' | 'multi'\n}\n\ntype ExtractMode = 'all' | 'split' | 'main'\n\n/** Extract-dialog state: the graph file being extracted. */\ninterface ExtractState {\n file: string\n analysis: GraphAnalysis | null\n error: string | null\n mode: ExtractMode\n}\n\n/** Read-only view state for a ComfyUI-side workflow. */\ninterface WorkflowViewState {\n file: string\n graph: Record<string, unknown>\n}\n\ninterface AssetEntry {\n promptId: string\n ts: string\n workflowName: string | null\n source: string\n media: MediaItem[]\n}\n\ntype JobStatus = 'pending' | 'in_progress' | 'completed' | 'failed' | 'cancelled'\n/** History filter: 'all' shows every terminal task; others narrow it. */\ntype JobFilter = 'all' | 'completed' | 'failed' | 'cancelled'\n\n/** One unified job from ComfyUI /api/jobs, as served by /comfyui/jobs. */\ninterface JobView {\n id: string\n status: JobStatus\n createTime: number | null\n executionStartTime: number | null\n executionEndTime: number | null\n executionError: { message?: string; exception_message?: string; node_type?: string } | null\n outputsCount: number\n previewOutput: { filename?: string; subfolder?: string; type?: string; mediaType?: string } | null\n workflowId: string | null\n workflowName: string | null\n ours: boolean\n progress: { value: number; max: number } | null\n}\n\ninterface JobsView {\n ok: boolean\n error?: string\n jobs: JobView[]\n total: number\n hasMore: boolean\n}\n\nconst JOB_FILTERS: Array<{ key: JobFilter; label: string }> = [\n { key: 'all', label: 'jobFilterAll' },\n { key: 'completed', label: 'jobFilterCompleted' },\n { key: 'failed', label: 'jobFilterFailed' },\n { key: 'cancelled', label: 'jobFilterCancelled' },\n]\n\n/** One adjustable parameter of a saved workflow (mirrors host WorkflowParameter). */\ninterface WorkflowParameter {\n id: string\n name: string\n label: string\n type: 'string' | 'number' | 'boolean'\n nodeId: string\n inputKey: string\n default: string | number | boolean\n description?: string\n random?: boolean\n options?: Array<string | number>\n upload?: 'image' | 'video' | 'audio' | 'media'\n subfolder?: string\n}\n\n/** Editing state for a workflow: the JSON field is text while being edited. */\ninterface WorkflowDraft {\n id?: string\n name?: string\n description?: string\n tags?: string[]\n inputs?: string\n workflow: string | Record<string, unknown>\n parameters?: WorkflowParameter[]\n updatedAt?: string\n}\n\nfunction shortId(promptId: string): string {\n return promptId.length > 10 ? `${promptId.slice(0, 10)}…` : promptId\n}\n\n/** Open a job's preview image URL (via the media proxy) when it has one. */\nfunction previewUrlOf(job: JobView): string | null {\n const preview = job.previewOutput\n if (preview === undefined || preview === null || preview.filename === undefined || preview.filename === null) return null\n return `/comfyui/media?file=${encodeURIComponent(preview.filename)}&subfolder=${encodeURIComponent(preview.subfolder ?? '')}&type=${encodeURIComponent(preview.type ?? 'output')}`\n}\n\n/** Opens a generated image in a large overlay with prev/next navigation. */\n\nfunction newParamId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') return crypto.randomUUID()\n return `p${Date.now().toString(36)}${Math.floor(Math.random() * 1e6).toString(36)}`\n}\n\n/** Parse the draft workflow into a plain object (empty on invalid JSON). */\nfunction parseDraftWorkflow(workflow: string | Record<string, unknown>): Record<string, unknown> {\n if (typeof workflow !== 'string') return workflow\n try {\n const parsed = JSON.parse(workflow) as unknown\n return typeof parsed === 'object' && parsed !== null ? (parsed as Record<string, unknown>) : {}\n } catch {\n return {}\n }\n}\n\n/**\n * Custom dropdown for loader-node file lists: each option shows a small\n * server-side thumbnail (images only; <select> cannot render images).\n */\nfunction UploadSelect(props: {\n value: string\n options: Array<string | number>\n kind: 'image' | 'video' | 'audio'\n onChange: (value: string) => void\n onRefresh?: () => Promise<Array<string | number> | undefined>\n}): ReturnType<typeof h> {\n const [open, setOpen] = useState(false)\n const [live, setLive] = useState<Array<string | number> | null>(null)\n const ref = useRef<HTMLDivElement | null>(null)\n // Keep the latest refresh callback without re-running the open-effect.\n const refreshRef = useRef(props.onRefresh)\n refreshRef.current = props.onRefresh\n\n useEffect(() => {\n if (!open) return\n const onDoc = (event: MouseEvent): void => {\n if (ref.current !== null && !ref.current.contains(event.target as Node)) setOpen(false)\n }\n document.addEventListener('mousedown', onDoc)\n return () => document.removeEventListener('mousedown', onDoc)\n }, [open])\n\n // Pull the live file list from the server every time the menu opens, so\n // files uploaded elsewhere show up without reloading the workflow editor.\n useEffect(() => {\n if (!open) return\n const fn = refreshRef.current\n if (fn === undefined) return\n let cancelled = false\n void fn().then((latest) => {\n if (!cancelled && latest !== undefined) setLive(latest)\n })\n return () => { cancelled = true }\n }, [open])\n\n const options = live ?? props.options\n const thumbUrl = (name: string | number): string | null =>\n props.kind === 'image' ? `/comfyui/media?file=${encodeURIComponent(String(name))}&type=input` : null\n const current = options.some((option) => String(option) === props.value) ? props.value : String(props.value)\n\n return h('div', { ref, className: 'dsc-upload-select' },\n h('button', {\n className: 'dsc-upload-select-btn',\n onClick: () => setOpen(!open),\n title: String(current),\n },\n thumbUrl(props.value) !== null\n ? h('img', { className: 'dsc-upload-select-thumb', src: thumbUrl(props.value) ?? '', alt: '', loading: 'lazy' })\n : null,\n h('span', { className: 'dsc-upload-select-name' }, String(current)),\n ),\n open\n ? h('div', { className: 'dsc-upload-select-pop' },\n options.map((option) => {\n const name = String(option)\n return h('div', {\n key: name,\n className: `dsc-upload-select-item${name === props.value ? ' dsc-upload-select-item--active' : ''}`,\n onClick: () => { props.onChange(name); setOpen(false) },\n },\n thumbUrl(option) !== null\n ? h('img', { className: 'dsc-upload-select-thumb', src: thumbUrl(option) ?? '', alt: '', loading: 'lazy' })\n : null,\n h('span', { className: 'dsc-upload-select-name' }, name),\n )\n }),\n )\n : null,\n )\n}\n\n/** Merge a freshly fetched option list with the previous one (latest first,\n * deduped) so the dropdown never drops options mid-session. */\nfunction mergeOptions(prev: Array<string | number>, latest: Array<string | number>): Array<string | number> {\n const seen = new Set<string>()\n const out: Array<string | number> = []\n for (const item of [...latest, ...prev]) {\n const key = String(item)\n if (!seen.has(key)) { seen.add(key); out.push(item) }\n }\n return out\n}\n\n/** Copy text to the clipboard; falls back to a hidden textarea when the\n * clipboard API is unavailable (non-secure LAN http). */\nfunction copyText(text: string): Promise<boolean> {\n if (navigator.clipboard !== undefined) {\n return navigator.clipboard.writeText(text).then(() => true).catch(() => copyViaTextarea(text))\n }\n return Promise.resolve(copyViaTextarea(text))\n}\n\nfunction copyViaTextarea(text: string): boolean {\n const textarea = document.createElement('textarea')\n textarea.value = text\n textarea.style.position = 'fixed'\n textarea.style.opacity = '0'\n document.body.appendChild(textarea)\n textarea.select()\n let ok = false\n try {\n ok = document.execCommand('copy')\n } catch {\n ok = false\n }\n document.body.removeChild(textarea)\n return ok\n}\n\n/** Read a file's pixel size in the browser (image only) and report it to the\n * plugin so the workflow output size can default to the source image. Returns\n * the size text for display, or undefined when unreadable. */\nasync function recordMediaSize(file: File, name: string): Promise<string | undefined> {\n try {\n const bitmap = await createImageBitmap(file)\n const width = bitmap.width\n const height = bitmap.height\n bitmap.close()\n await fetch('/comfyui/media-size', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ name, width, height }),\n }).catch(() => undefined)\n return `${width}×${height}`\n } catch {\n return undefined\n }\n}\n\n/** SHA-256 hex digest (pure JS — crypto.subtle needs a secure context, which a\n * LAN http origin is not). Uses the standard padding/compression; the input is\n * any byte array. */\nfunction sha256Hex(data: Uint8Array): string {\n const K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n ])\n const H = new Uint32Array([0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19])\n const len = data.length\n const total = len + 1 + (((56 - ((len + 1) % 64)) + 64) % 64) + 8\n const msg = new Uint8Array(total)\n msg.set(data)\n msg[len] = 0x80\n const bitLenLo = (len * 8) >>> 0\n const bitLenHi = Math.floor(len / 0x20000000)\n const dv = new DataView(msg.buffer)\n dv.setUint32(total - 8, bitLenHi)\n dv.setUint32(total - 4, bitLenLo)\n const w = new Uint32Array(64)\n for (let offset = 0; offset < total; offset += 64) {\n for (let i = 0; i < 16; i++) w[i] = dv.getUint32(offset + i * 4)\n for (let i = 16; i < 64; i++) {\n const s0 = ((w[i - 15]! >>> 7) | (w[i - 15]! << 25)) ^ ((w[i - 15]! >>> 18) | (w[i - 15]! << 14)) ^ (w[i - 15]! >>> 3)\n const s1 = ((w[i - 2]! >>> 17) | (w[i - 2]! << 15)) ^ ((w[i - 2]! >>> 19) | (w[i - 2]! << 13)) ^ (w[i - 2]! >>> 10)\n w[i] = (w[i - 16]! + s0 + w[i - 7]! + s1) >>> 0\n }\n let a = H[0]!, b = H[1]!, c = H[2]!, d = H[3]!, e = H[4]!, f = H[5]!, g = H[6]!, h = H[7]!\n for (let i = 0; i < 64; i++) {\n const S1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7))\n const ch = (e & f) ^ (~e & g)\n const temp1 = (h + S1 + ch + K[i]! + w[i]!) >>> 0\n const S0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10))\n const maj = (a & b) ^ (a & c) ^ (b & c)\n const temp2 = (S0 + maj) >>> 0\n h = g; g = f; f = e; e = (d + temp1) >>> 0; d = c; c = b; b = a; a = (temp1 + temp2) >>> 0\n }\n H[0] = (H[0]! + a) >>> 0; H[1] = (H[1]! + b) >>> 0; H[2] = (H[2]! + c) >>> 0; H[3] = (H[3]! + d) >>> 0\n H[4] = (H[4]! + e) >>> 0; H[5] = (H[5]! + f) >>> 0; H[6] = (H[6]! + g) >>> 0; H[7] = (H[7]! + h) >>> 0\n }\n let out = ''\n for (let i = 0; i < 8; i++) out += H[i]!.toString(16).padStart(8, '0')\n return out\n}\n\n/** `image.png` + hash → `image_3f9a2b1c0d.png`: keeps the name readable while\n * making it content-unique, so re-uploading the same file reuses the name. */\nfunction renameWithHash(original: string, hash: string): string {\n const short = hash.slice(0, 10)\n const dot = original.lastIndexOf('.')\n const base = dot > 0 ? original.slice(0, dot) : original\n const ext = dot > 0 ? original.slice(dot) : ''\n return `${base}_${short}${ext}`\n}\n\n/** Upload a file with content-hash naming and dedup: same bytes → same file\n * name, and (for root uploads) the existing file is reused instead of creating\n * a duplicate. Returns the file name on the ComfyUI server. */\nasync function uploadDedup(file: File, subfolder?: string): Promise<string> {\n const hash = sha256Hex(new Uint8Array(await file.arrayBuffer()))\n const dedup = subfolder === undefined || subfolder === ''\n if (dedup) {\n const lookup = await fetch('/comfyui/media-lookup', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ hash }),\n }).then((response) => response.json() as Promise<{ ok?: boolean; found?: boolean; name?: string }>).catch(() => undefined)\n if (lookup !== undefined && lookup.ok === true && lookup.found === true && typeof lookup.name === 'string') {\n return lookup.name\n }\n }\n const renamed = new File([file], renameWithHash(file.name, hash), { type: file.type })\n const form = new FormData()\n form.append('image', renamed)\n if (!dedup) form.append('subfolder', subfolder)\n const response = await fetch('/comfyui/upload', { method: 'POST', body: form })\n const data = (await response.json()) as { ok?: boolean; name?: string; error?: string }\n if (data.ok !== true || typeof data.name !== 'string') throw new Error(data.error ?? 'upload failed')\n if (dedup) {\n await fetch('/comfyui/media-hash', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ hash, name: data.name }),\n }).catch(() => undefined)\n }\n return data.name\n}\n\n/**\n * Parameter editor: lists the workflow's adjustable parameters (auto-detected\n * prompt/size/steps/seed) with editable name/label/default and a random\n * toggle for number parameters, plus an \"advanced\" picker that exposes any\n * node input as a custom parameter.\n */\nfunction ParameterEditor(props: {\n t: ComfyUIPanelProps['t']\n params: WorkflowParameter[]\n workflow: Record<string, unknown>\n onChange: (params: WorkflowParameter[]) => void\n}): ReturnType<typeof h> {\n const { t, params, workflow, onChange } = props\n const [advanced, setAdvanced] = useState(false)\n const [advNode, setAdvNode] = useState('')\n const [advInput, setAdvInput] = useState('')\n const [advLabel, setAdvLabel] = useState('')\n const [recognizing, setRecognizing] = useState(false)\n const [recognizeError, setRecognizeError] = useState<string | null>(null)\n const [uploading, setUploading] = useState<Record<string, boolean>>({})\n const [hovered, setHovered] = useState<string | null>(null)\n // Latest params/uploadFile for the global paste listener (bound once).\n const hoverRef = useRef<string | null>(null)\n const latestRef = useRef<{ params: WorkflowParameter[]; uploadFile: (param: WorkflowParameter, file: File) => Promise<void> }>({\n params,\n uploadFile: async () => undefined,\n })\n\n /** Re-fetch a parameter's live option list (ComfyUI input dir files) and\n * merge it into the stored options, so uploads made anywhere show up in the\n * dropdown without reloading the workflow editor. */\n const refreshOptions = async (param: WorkflowParameter): Promise<Array<string | number> | undefined> => {\n const rawNode = (workflow as Record<string, { class_type?: string }>)[param.nodeId]\n const classType = typeof rawNode?.class_type === 'string' ? rawNode.class_type : ''\n if (classType === '') return undefined\n const result = (await postJson('/comfyui/workflows/input-options', { classType, inputKey: param.inputKey })) as\n { ok?: boolean; options?: Array<string | number> }\n if (result.ok !== true || !Array.isArray(result.options)) return undefined\n const latest = result.options\n const index = params.findIndex((entry) => entry.id === param.id)\n if (index !== -1 && params[index]?.options !== undefined) {\n update(index, { options: mergeOptions(params[index]!.options!, latest) })\n }\n return latest\n }\n\n /** Upload a dropped file through the plugin proxy into ComfyUI's input dir. */\n const uploadFile = async (param: WorkflowParameter, file: File): Promise<void> => {\n setUploading((prev) => ({ ...prev, [param.id]: true }))\n try {\n const name = await uploadDedup(file, param.subfolder)\n void recordMediaSize(file, name)\n const index = params.findIndex((entry) => entry.id === param.id)\n if (index !== -1) update(index, { default: name })\n void refreshOptions(param)\n } finally {\n setUploading((prev) => ({ ...prev, [param.id]: false }))\n }\n }\n latestRef.current = { params, uploadFile }\n\n /** Global paste: Ctrl+V with the mouse hovering an upload parameter routes\n * the clipboard file (e.g. a screenshot) to that parameter — same mental\n * model as pasting an image into a chat input. */\n useEffect(() => {\n const onPaste = (event: ClipboardEvent): void => {\n const targetId = hoverRef.current\n if (targetId === null) return\n const file = event.clipboardData?.files?.[0]\n if (file === undefined) return\n const param = latestRef.current.params.find((entry) => entry.id === targetId)\n if (param === undefined || param.upload === undefined) return\n event.preventDefault()\n void latestRef.current.uploadFile(param, file)\n }\n document.addEventListener('paste', onPaste)\n return () => document.removeEventListener('paste', onPaste)\n }, [])\n\n /** Auto-generate the internal parameter name from the input key, deduped against existing params. */\n const genParamName = (base: string): string => {\n let name = base\n let index = 2\n while (params.some((param) => param.name === name)) name = `${base}_${index++}`\n return name\n }\n\n const nodeEntries = Object.entries(workflow).map(([id, raw]) => [id, raw as { class_type?: string; inputs?: Record<string, unknown> }] as const)\n const advNodeInfo = nodeEntries.find(([id]) => id === advNode)?.[1]\n const advInputs = advNodeInfo !== undefined && advNodeInfo.inputs !== undefined\n ? Object.entries(advNodeInfo.inputs).filter(([key]) => key !== 'upload')\n : []\n const selectedInput = advInputs.find(([key]) => key === advInput)\n\n /** Server-side auto-detection: prompt/size/steps/seed + dropdown options (object_info). */\n const recognize = async (): Promise<void> => {\n if (recognizing) return\n setRecognizing(true)\n setRecognizeError(null)\n try {\n const result = (await postJson('/comfyui/workflows/recognize', { workflow })) as { ok?: boolean; parameters?: WorkflowParameter[]; error?: string }\n if (result.ok === true && Array.isArray(result.parameters)) {\n onChange(result.parameters)\n setAdvanced(false)\n } else {\n setRecognizeError(result.error ?? t('wfParamsRecognizeFailed'))\n }\n } catch {\n setRecognizeError(t('wfParamsRecognizeFailed'))\n } finally {\n setRecognizing(false)\n }\n }\n\n const update = (index: number, patch: Partial<WorkflowParameter>): void => {\n onChange(params.map((param, i) => (i === index ? { ...param, ...patch } : param)))\n }\n\n const addAdvanced = async (): Promise<void> => {\n if (advNode === '' || advInput === '' || selectedInput === undefined || advNodeInfo === undefined) return\n const [, value] = selectedInput\n const type = typeof value === 'number' ? 'number' : typeof value === 'boolean' ? 'boolean' : 'string'\n\n // Generic media-list heuristic: a string holding a JSON array of\n // {kind, file, ...} items (e.g. MiniMaxH3 media_state) becomes one\n // reference-slot parameter per item. Detection is shape-based, never\n // class-specific.\n const existingMedia = params.some((param) => param.nodeId === advNode && param.inputKey === advInput && param.upload === 'media')\n if (!existingMedia && typeof value === 'string') {\n let parsed: unknown\n try {\n parsed = JSON.parse(value) as unknown\n } catch {\n parsed = undefined\n }\n if (Array.isArray(parsed) && parsed.length > 0\n && parsed.every((item) => typeof item === 'object' && item !== null && typeof (item as { file?: unknown }).file === 'string')) {\n const items = parsed as Array<{ name?: unknown; file?: unknown }>\n const firstFile = items[0]?.file\n const slash = typeof firstFile === 'string' ? firstFile.indexOf('/') : -1\n const subfolder = typeof firstFile === 'string' && slash > 0 ? firstFile.slice(0, slash) : undefined\n const added: WorkflowParameter[] = items.map((item, i) => ({\n id: newParamId(),\n name: genParamName(`media_${i + 1}`),\n label: `${t('wfRefSlot')}${i + 1}`,\n type: 'string',\n nodeId: advNode,\n inputKey: advInput,\n default: typeof item.name === 'string' ? item.name : '',\n upload: 'media',\n subfolder,\n }))\n onChange([...params, ...added])\n setAdvanced(false)\n setAdvNode('')\n setAdvInput('')\n setAdvLabel('')\n return\n }\n }\n\n // Ask the server for the node's dropdown options (object_info combos) and\n // whether this input is a loader file picker (upload kind).\n let options: Array<string | number> | undefined\n let upload: WorkflowParameter['upload']\n if (typeof advNodeInfo.class_type === 'string') {\n try {\n const result = (await postJson('/comfyui/workflows/input-options', { classType: advNodeInfo.class_type, inputKey: advInput })) as {\n ok?: boolean\n options?: Array<string | number>\n upload?: 'image' | 'video' | 'audio'\n }\n if (result.ok === true && Array.isArray(result.options) && result.options.length > 0) options = result.options\n upload = result.upload\n } catch {\n // options are a nice-to-have; fall back to free text\n }\n }\n onChange([...params, {\n id: newParamId(),\n name: genParamName(advInput),\n label: advLabel !== '' ? advLabel : `${advNode} · ${advInput}`,\n type,\n nodeId: advNode,\n inputKey: advInput,\n default: typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? value : '',\n options,\n upload,\n }])\n setAdvanced(false)\n setAdvNode('')\n setAdvInput('')\n setAdvLabel('')\n }\n\n /** Update a parameter's default; DynamicCombo parents refresh their child (size) parameter. */\n const updateDefault = (index: number, value: string | number | boolean): void => {\n update(index, { default: value })\n const param = params[index]\n if (param === undefined || typeof value !== 'string') return\n if (param.options === undefined || param.options.length === 0) return\n // Child parameter key is \"<parent>.<child>\" on the same node (e.g. aspect_ratio.size).\n const childIndex = params.findIndex((entry) => entry.nodeId === param.nodeId && entry.inputKey.startsWith(`${param.inputKey}.`))\n if (childIndex === -1) return\n const child = params[childIndex]\n if (child === undefined) return\n const rawNode = (workflow as Record<string, { class_type?: string }>)[child.nodeId]\n const classType = typeof rawNode?.class_type === 'string' ? rawNode.class_type : ''\n void postJson('/comfyui/workflows/input-options', { classType, inputKey: param.inputKey, parentValue: value })\n .then((result) => {\n const data = result as { ok?: boolean; child?: { childInputKey: string; options: Array<string | number>; default: string } }\n if (data.ok === true && data.child !== undefined && childIndex < params.length) {\n update(childIndex, { options: data.child.options, default: data.child.default })\n }\n })\n .catch(() => undefined)\n }\n\n return h('div', { className: 'dsc-params' },\n params.length === 0\n ? h('div', { className: 'dsc-hint' }, t('wfParamsEmpty'))\n : h('div', { className: 'dsc-list' }, params.map((param, index) => h('div', { key: param.id, className: 'dsc-param-row' },\n h('div', { className: 'dsc-param-fields' },\n h('input', {\n className: 'dsc-input dsc-input--sm',\n value: param.label,\n placeholder: t('wfParamLabel'),\n onChange: (event: { target: { value: string } }) => update(index, { label: event.target.value }),\n }),\n ),\n param.upload === 'media'\n ? h('div', {\n className: 'dsc-param-upload-wrap',\n onMouseEnter: () => { hoverRef.current = param.id; setHovered(param.id) },\n onMouseLeave: () => { hoverRef.current = null; setHovered(null) },\n },\n h('input', {\n className: 'dsc-input dsc-input--sm dsc-param-default',\n value: String(param.default),\n placeholder: t('wfMediaEmpty'),\n title: `${param.subfolder ?? ''}/`,\n onChange: (event: { target: { value: string } }) => updateDefault(index, event.target.value),\n }),\n h('label', {\n className: hovered === param.id ? 'dsc-dropzone dsc-dropzone--over' : 'dsc-dropzone',\n title: t('wfPasteHint'),\n tabIndex: 0,\n onDragOver: (event: { preventDefault: () => void }) => event.preventDefault(),\n onDrop: (event: { preventDefault: () => void; dataTransfer?: { files?: File[] } }) => {\n event.preventDefault()\n const file = event.dataTransfer?.files?.[0]\n if (file !== undefined) void uploadFile(param, file)\n },\n onPaste: (event: { clipboardData?: { files?: File[] } }) => {\n const file = event.clipboardData?.files?.[0]\n if (file !== undefined) void uploadFile(param, file)\n },\n },\n h('input', {\n type: 'file',\n style: { display: 'none' },\n onChange: (event: { target: HTMLInputElement }) => {\n const file = event.target.files?.[0]\n if (file !== undefined) void uploadFile(param, file)\n event.target.value = ''\n },\n }),\n uploading[param.id] === true ? t('wfParamsUploading') : t('wfParamsDrop'),\n ),\n h('button', { className: 'dsc-btn', onClick: () => updateDefault(index, '') }, t('wfMediaClear')),\n )\n : param.upload !== undefined\n ? h('div', {\n className: 'dsc-param-upload-wrap',\n onMouseEnter: () => { hoverRef.current = param.id; setHovered(param.id) },\n onMouseLeave: () => { hoverRef.current = null; setHovered(null) },\n },\n param.options !== undefined && param.options.length > 0\n ? h(UploadSelect, {\n value: String(param.default),\n options: param.options,\n kind: param.upload,\n onChange: (value: string) => updateDefault(index, value),\n onRefresh: () => refreshOptions(param),\n })\n : null,\n h('label', {\n className: hovered === param.id ? 'dsc-dropzone dsc-dropzone--over' : 'dsc-dropzone',\n title: t('wfPasteHint'),\n tabIndex: 0,\n onDragOver: (event: { preventDefault: () => void }) => event.preventDefault(),\n onDrop: (event: { preventDefault: () => void; dataTransfer?: { files?: File[] } }) => {\n event.preventDefault()\n const file = event.dataTransfer?.files?.[0]\n if (file !== undefined) void uploadFile(param, file)\n },\n onPaste: (event: { clipboardData?: { files?: File[] } }) => {\n const file = event.clipboardData?.files?.[0]\n if (file !== undefined) void uploadFile(param, file)\n },\n },\n h('input', {\n type: 'file',\n style: { display: 'none' },\n onChange: (event: { target: HTMLInputElement }) => {\n const file = event.target.files?.[0]\n if (file !== undefined) void uploadFile(param, file)\n event.target.value = ''\n },\n }),\n uploading[param.id] === true ? t('wfParamsUploading') : `${t('wfParamsDrop')} ${t(`uploadKind_${param.upload}`)}`,\n ),\n )\n : (param.options !== undefined && param.options.length > 0)\n ? h('select', {\n className: 'dsc-input dsc-input--sm dsc-param-default',\n value: String(param.default),\n onChange: (event: { target: { value: string } }) => updateDefault(index, event.target.value),\n },\n param.options.map((option) => h('option', { key: String(option), value: String(option) }, String(option))),\n )\n : param.type === 'string'\n ? h('textarea', {\n className: 'dsc-input dsc-param-default',\n rows: 2,\n value: String(param.default),\n placeholder: t('wfParamDefault'),\n onChange: (event: { target: { value: string } }) => updateDefault(index, event.target.value),\n })\n : h('input', {\n className: 'dsc-input dsc-input--sm dsc-param-default',\n value: String(param.default),\n placeholder: t('wfParamDefault'),\n onChange: (event: { target: { value: string } }) => {\n const raw = event.target.value\n updateDefault(index, param.type === 'number' ? (Number(raw) || 0) : raw)\n },\n }),\n h('div', { className: 'dsc-param-meta' },\n h('span', { className: 'dsc-meta' }, `${param.type} · #${param.nodeId}.${param.inputKey}`),\n param.type === 'number'\n ? h('label', { className: 'dsc-param-random' },\n h('input', {\n type: 'checkbox',\n checked: param.random === true,\n onChange: (event: { target: { checked: boolean } }) => update(index, { random: event.target.checked }),\n }),\n h('span', null, t('wfParamRandom')),\n )\n : null,\n h('button', { className: 'dsc-btn', onClick: () => onChange(params.filter((_, i) => i !== index)) }, t('wfParamDelete')),\n ),\n ))),\n h('div', { className: 'dsc-toolbar' },\n h('button', { className: 'dsc-btn', disabled: recognizing, onClick: () => { void recognize() } }, recognizing ? t('wfParamsRecognizing') : t('wfParamsRecognize')),\n h('button', { className: 'dsc-btn', onClick: () => setAdvanced(!advanced) }, t('wfParamsAdd')),\n ),\n recognizeError !== null ? h('div', { className: 'dsc-hint dsc-hint--error' }, recognizeError) : null,\n advanced\n ? h('div', { className: 'dsc-param-advanced' },\n h('div', { className: 'dsc-param-fields' },\n h('select', {\n className: 'dsc-input dsc-input--sm',\n value: advNode,\n onChange: (event: { target: { value: string } }) => { setAdvNode(event.target.value); setAdvInput('') },\n },\n h('option', { value: '' }, '—'),\n nodeEntries.map(([id, node]) => h('option', { key: id, value: id }, `#${id} ${node.class_type ?? ''}`)),\n ),\n advNodeInfo !== undefined\n ? h('select', {\n className: 'dsc-input dsc-input--sm',\n value: advInput,\n onChange: (event: { target: { value: string } }) => setAdvInput(event.target.value),\n },\n h('option', { value: '' }, '—'),\n advInputs\n .filter(([, value]) => value === null || typeof value !== 'object')\n .map(([key, value]) => h('option', { key, value: key }, `${key} (${value === null ? 'null' : typeof value})`)),\n )\n : null,\n h('input', {\n className: 'dsc-input dsc-input--sm',\n value: advLabel,\n placeholder: t('wfParamCustomLabel'),\n onChange: (event: { target: { value: string } }) => setAdvLabel(event.target.value),\n }),\n h('button', { className: 'dsc-btn', disabled: advNode === '' || advInput === '', onClick: () => { void addAdvanced() } }, t('wfParamAdd')),\n ),\n h('div', { className: 'dsc-hint' }, t('wfParamCustomHint')),\n )\n : null,\n )\n}\n\nfunction formatTs(ts: string): string {\n const date = new Date(ts)\n return Number.isNaN(date.getTime()) ? ts : date.toLocaleString()\n}\n\nfunction formatBytes(bytes: number | undefined): string {\n if (bytes === undefined) return ''\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(2)} MB`\n}\n\n/** The panel shell: header (drag handle), tabs, and the active tab body. */\nexport function ComfyUIPanel({ t }: ComfyUIPanelProps): ReturnType<typeof h> | null {\n const open = usePanelOpen()\n const tab = usePanelTab()\n const [geom, setGeom] = useState<PanelGeom>(loadGeom)\n const [dragging, setDragging] = useState<'move' | 'resize' | null>(null)\n const [lightbox, setLightbox] = useState<{ images: string[]; kinds: Array<'image' | 'video' | 'audio' | 'other'>; index: number } | null>(null)\n const panelRef = useRef<HTMLDivElement | null>(null)\n const dragRef = useRef<{ startX: number; startY: number; origX: number; origY: number; width: number; height: number } | null>(null)\n\n const openPreview = (images: string[], kinds: Array<'image' | 'video' | 'audio' | 'other'>, index: number): void => setLightbox({ images, kinds, index })\n\n useEffect(() => {\n if (open) return\n saveGeom(geom)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open])\n\n const startDrag = (event: PointerEventLike, mode: 'move' | 'resize'): void => {\n if (event.button !== 0) return\n if (mode === 'move') {\n const target = event.target as HTMLElement | null\n if (target !== null && target.closest('button, input, textarea, select, a, label')) return\n }\n const rect = panelRef.current?.getBoundingClientRect()\n if (rect === undefined) return\n dragRef.current = {\n startX: event.clientX, startY: event.clientY,\n origX: rect.left, origY: rect.top, width: rect.width, height: rect.height,\n }\n setDragging(mode)\n const el = event.currentTarget as HTMLElement | null\n if (el !== null && typeof el.setPointerCapture === 'function') el.setPointerCapture(event.pointerId)\n }\n\n const moveDrag = (event: PointerEventLike): void => {\n const d = dragRef.current\n if (d === null) return\n if (dragging === 'move') {\n setGeom((prev) => ({\n ...prev,\n x: Math.round(d.origX + event.clientX - d.startX),\n y: Math.round(d.origY + event.clientY - d.startY),\n }))\n } else if (dragging === 'resize') {\n const width = Math.max(300, Math.min(720, d.width + event.clientX - d.startX))\n const height = Math.max(200, Math.min(Math.max(300, window.innerHeight - 40), d.height + event.clientY - d.startY))\n setGeom((prev) => ({ ...prev, width, height }))\n }\n }\n\n const endDrag = (): void => {\n if (dragRef.current === null) return\n dragRef.current = null\n setDragging(null)\n setGeom((prev) => {\n saveGeom(prev)\n return prev\n })\n }\n\n if (!open) return null\n\n const panelStyle: Record<string, string> = {}\n if (geom.x !== undefined && geom.y !== undefined) {\n panelStyle.left = `${geom.x}px`\n panelStyle.top = `${geom.y}px`\n panelStyle.right = 'auto'\n panelStyle.bottom = 'auto'\n }\n if (geom.width !== undefined) panelStyle.width = `${geom.width}px`\n if (geom.height !== undefined) panelStyle.height = `${geom.height}px`\n\n return h('div',\n { ref: panelRef, className: `dsc-panel${dragging !== null ? ' dsc-panel--dragging' : ''}`, style: panelStyle },\n h('div', {\n className: 'dsc-panel-head',\n onPointerDown: (event: PointerEventLike) => startDrag(event, 'move'),\n onPointerMove: (event: PointerEventLike) => moveDrag(event),\n onPointerUp: () => endDrag(),\n onPointerCancel: () => endDrag(),\n },\n h('span', { className: 'dsc-panel-title' },\n h('span', { className: 'dsc-trigger-glyph' }, h(ComfyUIIcon)),\n h('span', null, t('panelTitle')),\n ),\n h('button', {\n className: 'dsc-panel-close',\n 'aria-label': t('close'),\n onClick: () => panelStore.close(),\n }, '✕'),\n ),\n h('div', { className: 'dsc-tabs' },\n h(TabButton, { t, active: tab === 'workflows', label: t('tabWorkflows'), onClick: () => panelStore.setTab('workflows') }),\n h(TabButton, { t, active: tab === 'assets', label: t('tabAssets'), onClick: () => panelStore.setTab('assets') }),\n h(TabButton, { t, active: tab === 'queue', label: t('tabQueue'), onClick: () => panelStore.setTab('queue') }),\n ),\n h('div', { className: 'dsc-panel-body' },\n tab === 'workflows' ? h(WorkflowsTab, { t })\n : tab === 'assets' ? h(AssetsTab, { t, onPreview: openPreview })\n : h(QueueTab, { t, onPreview: openPreview }),\n ),\n lightbox !== null ? h(Lightbox, {\n t,\n images: lightbox.images,\n kinds: lightbox.kinds,\n index: lightbox.index,\n onClose: () => setLightbox(null),\n onIndex: (index: number) => setLightbox({ images: lightbox.images, kinds: lightbox.kinds, index }),\n }) : null,\n h('div', {\n className: 'dsc-panel-resize',\n onPointerDown: (event: PointerEventLike) => startDrag(event, 'resize'),\n onPointerMove: (event: PointerEventLike) => moveDrag(event),\n onPointerUp: () => endDrag(),\n onPointerCancel: () => endDrag(),\n }),\n )\n}\n\nfunction TabButton(props: { t: ComfyUIPanelProps['t']; active: boolean; label: string; onClick: () => void }): ReturnType<typeof h> {\n return h('button', {\n className: props.active ? 'dsc-tab dsc-tab--active' : 'dsc-tab',\n onClick: props.onClick,\n }, props.label)\n}\n\nfunction ErrorNote({ t, message }: { t: ComfyUIPanelProps['t']; message: string }): ReturnType<typeof h> {\n return h('div', { className: 'dsc-err' }, `${t('error')}: ${message}`)\n}\n\n/** Tab 1: workflow library — plugin library + ComfyUI-side saved workflows. */\n/** One selectable item in the load-area picker (mirrors the host response). */\ninterface LoadAreaFile {\n name: string\n kind: 'image' | 'video' | 'audio'\n url: string\n source: 'imported' | 'generated'\n ts?: string\n workflowName?: string | null\n width?: number\n height?: number\n}\n\n/** Load area at the bottom of the workflow library, modeled on the ComfyUI\n * LoadImage node: a big preview of the currently selected image; clicking it\n * opens a picker (全部/已导入/已生成 tabs + paste-to-upload + masonry grid).\n * Selecting a file makes it the default source image for image-to-image runs\n * (the workflow's image parameter defaults to this file name). */\nfunction LoadArea(props: { t: ComfyUIPanelProps['t']; onNotice: (message: string) => void }): ReturnType<typeof h> {\n const [current, setCurrent] = useState<LoadAreaFile | null>(null)\n const [files, setFiles] = useState<LoadAreaFile[]>([])\n const [pickerOpen, setPickerOpen] = useState(false)\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n const refresh = useCallback(async (): Promise<void> => {\n const data = (await fetch('/comfyui/loadarea').then((response) => response.json()).catch(() => undefined)) as\n { ok?: boolean; current?: LoadAreaFile | null; files?: LoadAreaFile[] } | undefined\n if (data?.ok === true) {\n setCurrent(data.current ?? null)\n setFiles(data.files ?? [])\n }\n }, [])\n\n useEffect(() => { void refresh() }, [refresh])\n\n const upload = async (file: File): Promise<string> => {\n setBusy(true)\n setError(null)\n try {\n const name = await uploadDedup(file)\n const sizeText = await recordMediaSize(file, name)\n await refresh()\n props.onNotice(`${props.t('wfUploaded')}:${name}${sizeText !== undefined ? `(${sizeText})` : ''}`)\n return name\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n throw cause\n } finally {\n setBusy(false)\n }\n }\n\n const pick = async (file: LoadAreaFile): Promise<void> => {\n await fetch('/comfyui/current-image', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ name: file.name, kind: file.kind, source: file.source }),\n }).catch(() => undefined)\n setCurrent(file)\n setPickerOpen(false)\n props.onNotice(`${props.t('wfLoadPicked')}:${file.name}`)\n }\n\n return h('div', { className: 'dsc-loadarea' },\n h('div', { className: 'dsc-loadarea-head' },\n h('span', { className: 'dsc-loadarea-title' }, props.t('wfLoadArea')),\n h('span', { className: 'dsc-meta' }, props.t('wfLoadHint')),\n ),\n h('button', {\n className: 'dsc-loadarea-main',\n onClick: () => setPickerOpen(true),\n title: props.t('wfLoadHint'),\n disabled: busy,\n },\n current !== null\n ? h('img', { className: 'dsc-loadarea-img', src: current.url, alt: '', loading: 'lazy' })\n : h('span', { className: 'dsc-loadarea-empty' }, props.t('wfLoadEmpty')),\n h('span', { className: 'dsc-loadarea-name' },\n current !== null\n ? `${current.name}${current.width !== undefined && current.height !== undefined ? `(${current.width}×${current.height})` : ''}`\n : '',\n ),\n ),\n pickerOpen\n ? h(LoadPicker, { t: props.t, files, current: current?.name ?? null, onUpload: upload, onPick: pick, onClose: () => setPickerOpen(false) })\n : null,\n error !== null ? h('div', { className: 'dsc-hint dsc-hint--error' }, error) : null,\n )\n}\n\n/** The load-area picker dialog: tab bar (全部/已导入/已生成) with a\n * paste/click upload zone on the right, and a masonry image grid below. */\nfunction LoadPicker(props: {\n t: ComfyUIPanelProps['t']\n files: LoadAreaFile[]\n current: string | null\n onUpload: (file: File) => Promise<string>\n onPick: (file: LoadAreaFile) => Promise<void>\n onClose: () => void\n}): ReturnType<typeof h> {\n const [tab, setTab] = useState<'all' | 'imported' | 'generated'>('all')\n const [type, setType] = useState<'all' | 'image' | 'video' | 'audio'>('all')\n const hoverRef = useRef(false)\n const [uploadFlash, setUploadFlash] = useState<string | null>(null)\n const [scrollTo, setScrollTo] = useState<string | null>(null)\n const cardRefs = useRef<Map<string, HTMLElement>>(new Map())\n const flashTimer = useRef<number | undefined>(undefined)\n\n useEffect(() => () => {\n if (flashTimer.current !== undefined) window.clearTimeout(flashTimer.current)\n }, [])\n\n useEffect(() => {\n const onPaste = (event: ClipboardEvent): void => {\n if (!hoverRef.current) return\n const file = event.clipboardData?.files?.[0]\n if (file === undefined) return\n event.preventDefault()\n void handleUpload(file)\n }\n document.addEventListener('paste', onPaste)\n return () => document.removeEventListener('paste', onPaste)\n })\n\n /** Upload, then flash a confirmation and scroll the grid to the new file. */\n const handleUpload = async (file: File): Promise<void> => {\n try {\n const name = await props.onUpload(file)\n setScrollTo(name)\n setUploadFlash(`${props.t('wfUploadedToast')}:${name}`)\n if (flashTimer.current !== undefined) window.clearTimeout(flashTimer.current)\n flashTimer.current = window.setTimeout(() => setUploadFlash(null), 2500)\n } catch {\n // LoadArea shows the upload error in its own area.\n }\n }\n\n const bySource = tab === 'all' ? props.files : props.files.filter((file) => file.source === tab)\n const filtered = type === 'all' ? bySource : bySource.filter((file) => file.kind === type)\n\n // After the refreshed file list renders, scroll the matching card into view.\n useEffect(() => {\n if (scrollTo === null) return\n let found: HTMLElement | undefined\n for (const [key, el] of cardRefs.current) {\n if (key.endsWith(`:${scrollTo}`)) { found = el; break }\n }\n if (found !== undefined) {\n found.scrollIntoView({ block: 'center', behavior: 'smooth' })\n setScrollTo(null)\n }\n }, [scrollTo, filtered])\n // Distribute into 3 vertical columns (round-robin) — a masonry look that\n // scrolls reliably, unlike CSS multi-column which balances columns to the\n // container height and never overflows.\n const columns: LoadAreaFile[][] = [[], [], []]\n filtered.forEach((file, index) => { columns[index % 3]!.push(file) })\n const tabs: Array<{ id: 'all' | 'imported' | 'generated'; label: string }> = [\n { id: 'all', label: props.t('wfTabAll') },\n { id: 'imported', label: props.t('wfTabImported') },\n { id: 'generated', label: props.t('wfTabGenerated') },\n ]\n const typeOptions: Array<{ id: 'all' | 'image' | 'video' | 'audio'; label: string }> = [\n { id: 'all', label: props.t('wfTypeAll') },\n { id: 'image', label: props.t('uploadKind_image') },\n { id: 'video', label: props.t('uploadKind_video') },\n { id: 'audio', label: props.t('uploadKind_audio') },\n ]\n\n return h('div', { className: 'dsc-picker-overlay', onClick: props.onClose },\n h('div', { className: 'dsc-picker', onClick: (event: { stopPropagation: () => void }) => event.stopPropagation() },\n h('div', { className: 'dsc-picker-bar' },\n h('div', { className: 'dsc-picker-tabs' },\n tabs.map((entry) => h('button', {\n key: entry.id,\n className: `dsc-picker-tab${tab === entry.id ? ' dsc-picker-tab--active' : ''}`,\n onClick: () => setTab(entry.id),\n }, entry.label)),\n ),\n h('label', {\n className: 'dsc-dropzone dsc-picker-upload',\n title: props.t('wfPasteHint'),\n onMouseEnter: () => { hoverRef.current = true },\n onMouseLeave: () => { hoverRef.current = false },\n onDragOver: (event: { preventDefault: () => void }) => event.preventDefault(),\n onDrop: (event: { preventDefault: () => void; dataTransfer?: { files?: File[] } }) => {\n event.preventDefault()\n const file = event.dataTransfer?.files?.[0]\n if (file !== undefined) void handleUpload(file)\n },\n },\n h('input', {\n type: 'file',\n style: { display: 'none' },\n onChange: (event: { target: HTMLInputElement }) => {\n const file = event.target.files?.[0]\n if (file !== undefined) void handleUpload(file)\n event.target.value = ''\n },\n }),\n props.t('wfPickerUpload'),\n ),\n h('select', {\n className: 'dsc-picker-type',\n value: type,\n onChange: (event: { target: { value: string } }) => setType(event.target.value as 'all' | 'image' | 'video' | 'audio'),\n }, typeOptions.map((option) => h('option', { key: option.id, value: option.id }, option.label))),\n ),\n filtered.length === 0\n ? h('div', { className: 'dsc-picker-empty' }, props.t('wfLoadNoFiles'))\n : h('div', { className: 'dsc-picker-grid' },\n columns.map((column, columnIndex) => h('div', { key: columnIndex, className: 'dsc-picker-col' },\n column.map((file) => h('button', {\n key: `${file.source}:${file.name}`,\n className: `dsc-picker-card${file.name === props.current ? ' dsc-picker-card--active' : ''}`,\n onClick: () => { void props.onPick(file) },\n title: file.name,\n ref: (el: HTMLElement | null): void => {\n if (el !== null) cardRefs.current.set(`${file.source}:${file.name}`, el)\n else cardRefs.current.delete(`${file.source}:${file.name}`)\n },\n },\n file.kind === 'image'\n ? h('img', { className: 'dsc-picker-thumb', src: file.url, alt: '', loading: 'lazy' })\n : h('span', { className: 'dsc-picker-thumb dsc-picker-thumb--media' }, file.kind === 'video' ? '🎞' : '🎵'),\n h('span', { className: 'dsc-picker-name' }, file.name),\n file.width !== undefined && file.height !== undefined\n ? h('span', { className: 'dsc-meta' }, `${file.width}×${file.height}`)\n : null,\n )),\n )),\n ),\n uploadFlash !== null ? h('div', { className: 'dsc-picker-toast' }, uploadFlash) : null,\n ),\n )\n}\n\n/** Tag editor: preset classification chips (图生图 etc.) toggle on/off, plus\n * free-form custom tags added with Enter and removed by clicking. */\nfunction TagEditor(props: {\n t: ComfyUIPanelProps['t']\n tags: string[]\n onChange: (tags: string[]) => void\n}): ReturnType<typeof h> {\n const [custom, setCustom] = useState('')\n\n const toggle = (tag: string): void => {\n props.onChange(props.tags.includes(tag) ? props.tags.filter((entry) => entry !== tag) : [...props.tags, tag])\n }\n\n const addCustom = (): void => {\n const tag = custom.trim()\n if (tag === '' || props.tags.includes(tag)) return\n props.onChange([...props.tags, tag])\n setCustom('')\n }\n\n const customTags = props.tags.filter((tag) => !PRESET_TAGS.includes(tag))\n\n return h('div', { className: 'dsc-tag-editor' },\n h('div', { className: 'dsc-tag-row' },\n PRESET_TAGS.map((tag) => h('button', {\n key: tag,\n className: `dsc-tag-chip${props.tags.includes(tag) ? ' dsc-tag-chip--active' : ''}`,\n onClick: () => toggle(tag),\n }, tag)),\n ),\n customTags.length > 0\n ? h('div', { className: 'dsc-tag-row' },\n customTags.map((tag) => h('button', {\n key: tag,\n className: 'dsc-tag-chip dsc-tag-chip--active',\n title: props.t('wfTagRemove'),\n onClick: () => toggle(tag),\n }, `✕ ${tag}`)),\n )\n : null,\n h('input', {\n className: 'dsc-input dsc-input--sm dsc-tag-input',\n value: custom,\n placeholder: props.t('wfTagAdd'),\n onChange: (event: { target: { value: string } }) => setCustom(event.target.value),\n onKeyDown: (event: { key: string; preventDefault: () => void }) => {\n if (event.key === 'Enter') { event.preventDefault(); addCustom() }\n },\n }),\n )\n}\n\nfunction WorkflowsTab({ t }: ComfyUIPanelProps): ReturnType<typeof h> {\n const [list, setList] = useState<WorkflowEntry[] | null>(null)\n const [comfyui, setComfyui] = useState<ComfyUIWorkflowEntry[] | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [comfyuiError, setComfyuiError] = useState<string | null>(null)\n const [notice, setNotice] = useState<string | null>(null)\n const [editing, setEditing] = useState<WorkflowDraft | null>(null)\n const [busy, setBusy] = useState(false)\n const [viewing, setViewing] = useState<WorkflowViewState | null>(null)\n const [extract, setExtract] = useState<ExtractState | null>(null)\n const [tagFilter, setTagFilter] = useState<string | null>(null)\n\n const load = async (): Promise<void> => {\n try {\n const data = await getJson<{ workflows: WorkflowEntry[] }>('/comfyui/workflows')\n setList(data.workflows)\n setError(null)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n }\n try {\n const data = await getJson<{ workflows: ComfyUIWorkflowEntry[] }>('/comfyui/comfy-workflows')\n setComfyui(data.workflows)\n setComfyuiError(null)\n } catch (cause) {\n setComfyuiError(cause instanceof Error ? cause.message : String(cause))\n }\n }\n\n useEffect(() => {\n let cancelled = false\n void getJson<{ workflows: WorkflowEntry[] }>('/comfyui/workflows').then((data) => {\n if (!cancelled) setList(data.workflows)\n }).catch((cause: unknown) => {\n if (!cancelled) setError(cause instanceof Error ? cause.message : String(cause))\n })\n void getJson<{ workflows: ComfyUIWorkflowEntry[] }>('/comfyui/comfy-workflows').then((data) => {\n if (!cancelled) setComfyui(data.workflows)\n }).catch((cause: unknown) => {\n if (!cancelled) setComfyuiError(cause instanceof Error ? cause.message : String(cause))\n })\n return () => {\n cancelled = true\n }\n }, [])\n\n /** Persist the current draft; returns the saved workflow id, or null on failure (error already set). */\n const persist = async (): Promise<string | null> => {\n if (editing === null) return null\n setBusy(true)\n setError(null)\n setNotice(null)\n let workflow: unknown\n if (typeof editing.workflow === 'string') {\n try {\n workflow = JSON.parse(editing.workflow)\n } catch {\n setError(t('wfJsonError'))\n setBusy(false)\n return null\n }\n } else {\n workflow = editing.workflow\n }\n try {\n const body: Record<string, unknown> = {\n name: String(editing.name ?? ''),\n description: String(editing.description ?? ''),\n workflow,\n parameters: editing.parameters ?? [],\n tags: editing.tags ?? [],\n }\n if (editing.id !== undefined) body.id = editing.id\n const result = (await postJson('/comfyui/workflows', body)) as { workflow?: { id?: string } }\n return result.workflow?.id ?? (typeof editing.id === 'string' ? editing.id : null)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n return null\n } finally {\n setBusy(false)\n }\n }\n\n const save = async (): Promise<void> => {\n const id = await persist()\n if (id === null) return\n setEditing(null)\n await load()\n }\n\n /** Save the draft, then immediately queue it with the saved parameters. */\n const saveAndRun = async (): Promise<void> => {\n const id = await persist()\n if (id === null) return\n setEditing(null)\n await load()\n await run(id)\n }\n\n const run = async (id: string): Promise<void> => {\n setBusy(true)\n setError(null)\n setNotice(null)\n try {\n const result = (await postJson('/comfyui/workflows/run', { id })) as { promptId: string }\n setNotice(`${t('wfQueued')} ${shortId(result.promptId)}`)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setBusy(false)\n }\n }\n\n const remove = async (id: string): Promise<void> => {\n setBusy(true)\n setError(null)\n try {\n await postJson('/comfyui/workflows/delete', { id })\n await load()\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setBusy(false)\n }\n }\n\n const openExtract = (file: string): void => {\n setError(null)\n setExtract({ file, analysis: null, error: null, mode: 'split' })\n }\n\n const runExtract = async (state: ExtractState): Promise<void> => {\n setBusy(true)\n try {\n const data = (await postJson('/comfyui/comfy-workflows/extract', { file: state.file, mode: state.mode })) as { ok: boolean; saved: WorkflowEntry[]; warnings: string[]; error?: string }\n if (data.ok !== true) throw new Error(data.error ?? 'failed to extract')\n setNotice(`${state.file} → ${t('wfExtractedNotice')}${data.warnings.length > 0 ? `(${t('error')}: ${data.warnings.join(';')})` : ''}`)\n setExtract(null)\n await load()\n } catch (cause) {\n setExtract({ ...state, error: cause instanceof Error ? cause.message : String(cause) })\n } finally {\n setBusy(false)\n }\n }\n\n const importFile = (file: File): void => {\n const reader = new FileReader()\n reader.onload = () => {\n try {\n const parsed = JSON.parse(String(reader.result)) as unknown\n setEditing({ name: file.name.replace(/\\.json$/i, ''), workflow: parsed as Record<string, unknown> })\n setError(null)\n } catch {\n setError(t('wfJsonError'))\n }\n }\n reader.readAsText(file)\n }\n\n const view = async (file: string): Promise<void> => {\n setBusy(true)\n setError(null)\n try {\n const data = await getJson<{ ok: boolean; workflow?: Record<string, unknown>; error?: string }>(`/comfyui/comfy-workflows?file=${encodeURIComponent(file)}`)\n if (data.ok !== true || data.workflow === undefined) {\n throw new Error(data.error ?? 'failed to read workflow')\n }\n setViewing({ file, graph: data.workflow })\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setBusy(false)\n }\n }\n\n if (viewing !== null) {\n return h(WorkflowView, { t, file: viewing.file, graph: viewing.graph, onBack: () => setViewing(null) })\n }\n if (extract !== null) {\n return h(ExtractDialog, { t, state: extract, onUpdate: setExtract, onRun: (state) => runExtract(state), onClose: () => setExtract(null) })\n }\n if (error !== null) return h('div', null, h(ErrorNote, { t, message: error }))\n if (list === null) return h('div', { className: 'dsc-meta' }, '…')\n\n if (editing !== null) {\n return h('div', { className: 'dsc-form' },\n h('div', { className: 'dsc-field' },\n h('label', null, t('wfName')),\n h('input', { className: 'dsc-input', value: editing.name ?? '', onChange: (event: { target: { value: string } }) => setEditing({ ...editing, name: event.target.value }) }),\n ),\n h('div', { className: 'dsc-field' },\n h('label', null, t('wfDesc')),\n h('textarea', { className: 'dsc-textarea', placeholder: t('wfDescPlaceholder'), value: editing.description ?? '', onChange: (event: { target: { value: string } }) => setEditing({ ...editing, description: event.target.value }) }),\n ),\n h('div', { className: 'dsc-field' },\n h('label', null, t('wfTags')),\n h(TagEditor, { t, tags: editing.tags ?? [], onChange: (tags) => setEditing({ ...editing, tags }) }),\n ),\n h('div', { className: 'dsc-field' },\n h('label', null, t('wfParams')),\n h(ParameterEditor, {\n t,\n params: editing.parameters ?? [],\n workflow: parseDraftWorkflow(editing.workflow),\n onChange: (parameters) => setEditing({ ...editing, parameters }),\n }),\n ),\n h('div', { className: 'dsc-field' },\n h('label', null, t('wfJson')),\n h('textarea', {\n className: 'dsc-textarea dsc-textarea--json',\n value: typeof editing.workflow === 'string' ? editing.workflow : JSON.stringify(editing.workflow ?? {}, null, 2),\n onChange: (event: { target: { value: string } }) => setEditing({ ...editing, workflow: event.target.value }),\n }),\n ),\n notice !== null ? h('div', { className: 'dsc-ok' }, notice) : null,\n error !== null ? h(ErrorNote, { t, message: error }) : null,\n h('div', { className: 'dsc-row' },\n h('button', { className: 'dsc-btn', disabled: busy, onClick: () => void save() }, t('wfSave')),\n h('button', { className: 'dsc-btn', disabled: busy, onClick: () => void saveAndRun() }, t('wfSaveRun')),\n h('button', { className: 'dsc-btn', disabled: busy, onClick: () => { setEditing(null); setError(null) } }, t('wfCancel')),\n ),\n )\n }\n\n const comfyuiFold = h('details', { className: 'dsc-fold' },\n h('summary', null, `${t('wfComfyuiSection')} (${comfyui?.length ?? 0})`),\n h('div', { className: 'dsc-fold-body' },\n h('div', { className: 'dsc-hint' }, t('wfComfyuiHint')),\n comfyuiError !== null ? h(ErrorNote, { t, message: comfyuiError }) : null,\n comfyui === null\n ? h('div', { className: 'dsc-meta' }, '…')\n : comfyui.length === 0\n ? h('div', { className: 'dsc-meta' }, t('wfComfyuiEmpty'))\n : h('div', { className: 'dsc-list' }, comfyui.map((workflow) => h('div', { key: workflow.name, className: 'dsc-wf dsc-wf--comfyui', title: t('wfNameCopyHint'), onClick: () => { void copyText(workflow.name).then((ok) => { if (ok) setNotice(`${t('wfNameCopied')}:${workflow.name}`) }) } },\n h('div', { className: 'dsc-wf-col' },\n h('div', { className: 'dsc-wf-name', title: workflow.name }, workflow.name),\n h('div', { className: 'dsc-wf-actions' },\n h('button', { className: 'dsc-btn', disabled: busy, onClick: (event: { stopPropagation: () => void }) => { event.stopPropagation(); void view(workflow.name) } }, t('wfView')),\n h('button', { className: 'dsc-btn', disabled: busy, onClick: (event: { stopPropagation: () => void }) => { event.stopPropagation(); openExtract(workflow.name) } }, t('wfExtract')),\n ),\n h('div', { className: 'dsc-meta' }, [formatBytes(workflow.size), workflow.modified !== undefined ? formatTs(new Date(workflow.modified).toISOString()) : ''].filter(Boolean).join(' · ')),\n ),\n h('span', { className: workflow.extracted ? 'dsc-badge dsc-badge--ok' : 'dsc-badge dsc-badge--warn' }, workflow.extracted ? `${t('wfExtracted')} ${workflow.derived.length}` : t('wfNotExtracted')),\n ))),\n ),\n )\n\n // Tag filter bar: every tag present in the library, preset order first,\n // with counts; null = all workflows.\n const tagCounts = new Map<string, number>()\n for (const workflow of list) {\n for (const tag of workflow.tags ?? []) tagCounts.set(tag, (tagCounts.get(tag) ?? 0) + 1)\n }\n const visibleTags = [...tagCounts.entries()].sort((a, b) => {\n const pa = PRESET_TAGS.indexOf(a[0])\n const pb = PRESET_TAGS.indexOf(b[0])\n if (pa !== -1 && pb !== -1) return pa - pb\n if (pa !== -1) return -1\n if (pb !== -1) return 1\n return b[1] - a[1]\n }).map(([tag]) => tag)\n const visibleList = tagFilter === null ? list : list.filter((workflow) => (workflow.tags ?? []).includes(tagFilter))\n\n const apiFold = h('details', { className: 'dsc-fold', open: true },\n h('summary', null, `${t('wfLibrarySection')} (${visibleList.length})`),\n h('div', { className: 'dsc-fold-body' },\n visibleTags.length > 0 || tagFilter !== null\n ? h('div', { className: 'dsc-tag-filter' },\n h('button', {\n className: `dsc-tag-chip${tagFilter === null ? ' dsc-tag-chip--active' : ''}`,\n onClick: () => setTagFilter(null),\n }, `${t('wfTagAll')} (${list.length})`),\n visibleTags.map((tag) => h('button', {\n key: tag,\n className: `dsc-tag-chip${tagFilter === tag ? ' dsc-tag-chip--active' : ''}`,\n onClick: () => setTagFilter(tagFilter === tag ? null : tag),\n }, `${tag} (${tagCounts.get(tag) ?? 0})`)),\n )\n : null,\n visibleList.length === 0\n ? h('div', { className: 'dsc-meta' }, t('wfEmpty'))\n : h('div', { className: 'dsc-list' }, visibleList.map((workflow) => h('div', { key: workflow.id, className: 'dsc-wf', title: t('wfNameCopyHint'), onClick: () => { void copyText(workflow.name).then((ok) => { if (ok) setNotice(`${t('wfNameCopied')}:${workflow.name}`) }) } },\n h('div', { className: 'dsc-wf-top' },\n h('div', { className: 'dsc-wf-name', title: workflow.name }, workflow.name),\n (workflow.tags ?? []).length > 0\n ? h('div', { className: 'dsc-wf-tags' }, (workflow.tags ?? []).map((tag) => h('span', { key: tag, className: 'dsc-tag-chip dsc-tag-chip--mini' }, tag)))\n : null,\n ),\n workflow.description !== '' ? h('div', { className: 'dsc-wf-desc' }, workflow.description) : null,\n h('div', { className: 'dsc-wf-updated' }, `${t('wfUpdated')} ${formatTs(workflow.updatedAt)}`),\n h('div', { className: 'dsc-wf-actions' },\n h('button', { className: 'dsc-btn', disabled: busy, onClick: (event: { stopPropagation: () => void }) => { event.stopPropagation(); void run(workflow.id) } }, t('wfRun')),\n h('button', { className: 'dsc-btn', disabled: busy, onClick: (event: { stopPropagation: () => void }) => { event.stopPropagation(); setEditing({ ...workflow, workflow: JSON.stringify(workflow.workflow, null, 2), parameters: workflow.parameters ?? [], tags: workflow.tags ?? [] }); setError(null) } }, t('wfEdit')),\n h('button', { className: 'dsc-btn', disabled: busy, onClick: (event: { stopPropagation: () => void }) => { event.stopPropagation(); void remove(workflow.id) } }, t('wfDelete')),\n ),\n ))),\n ),\n )\n\n return h('div', null,\n h('div', { className: 'dsc-toolbar' },\n h('button', { className: 'dsc-btn', disabled: busy, onClick: () => { setEditing({ workflow: {}, parameters: [], tags: [] }); setError(null) } }, t('wfAdd')),\n h('label', { className: 'dsc-btn' },\n t('wfImportFile'),\n h('input', {\n type: 'file',\n accept: '.json,application/json',\n style: { display: 'none' },\n onChange: (event: { target: HTMLInputElement }) => {\n const file = event.target.files?.[0]\n if (file !== undefined) importFile(file)\n event.target.value = ''\n },\n }),\n ),\n h('button', { className: 'dsc-btn', disabled: busy, onClick: () => void load() }, t('wfRefresh')),\n ),\n notice !== null ? h('div', { className: 'dsc-ok' }, notice) : null,\n comfyuiFold,\n apiFold,\n h(LoadArea, { t, onNotice: setNotice }),\n )\n}\n\n/** Extract-mode chooser: shows the canvas analysis and lets the user pick how\n * to extract runnable API workflows from a ComfyUI-side graph. */\nfunction ExtractDialog(props: {\n t: ComfyUIPanelProps['t']\n state: ExtractState\n onUpdate: (state: ExtractState) => void\n onRun: (state: ExtractState) => Promise<void>\n onClose: () => void\n}): ReturnType<typeof h> {\n const { t, state, onUpdate, onRun, onClose } = props\n useEffect(() => {\n if (state.analysis === null && state.error === null) {\n let cancelled = false\n void getJson<{ ok: boolean; analysis?: GraphAnalysis; error?: string }>(`/comfyui/comfy-workflows/analyze?file=${encodeURIComponent(state.file)}`)\n .then((data) => {\n if (cancelled) return\n if (data.ok !== true || data.analysis === undefined) onUpdate({ ...state, error: data.error ?? 'failed to analyze' })\n else onUpdate({ ...state, analysis: data.analysis, mode: data.analysis.mode === 'single' ? 'all' : 'split' })\n })\n .catch((cause: unknown) => {\n if (!cancelled) onUpdate({ ...state, error: cause instanceof Error ? cause.message : String(cause) })\n })\n return () => {\n cancelled = true\n }\n }\n return undefined\n })\n\n const modes: Array<{ mode: ExtractMode; label: string; hint: string }> = [\n { mode: 'all', label: t('wfExtractModeAll'), hint: t('wfExtractModeAllHint') },\n { mode: 'split', label: t('wfExtractModeSplit'), hint: t('wfExtractModeSplitHint') },\n { mode: 'main', label: t('wfExtractModeMain'), hint: t('wfExtractModeMainHint') },\n ]\n const analysis = state.analysis\n return h('div', { className: 'dsc-dialog' },\n h('div', { className: 'dsc-dialog-head' },\n h('span', { className: 'dsc-wf-name' }, `${t('wfExtractTitle')}: ${state.file}`),\n h('button', { className: 'dsc-panel-close', 'aria-label': t('close'), onClick: onClose }, '✕'),\n ),\n analysis === null\n ? h('div', { className: 'dsc-meta' }, '…')\n : h('div', null,\n h('div', { className: 'dsc-hint' },\n `${t('wfComponents')}: ${analysis.components.length} · ${t('wfBypassed')}: ${analysis.bypassedCount} · ${t('wfIsolated')}: ${analysis.isolated.length}`,\n ),\n analysis.components.length > 0\n ? h('ul', { className: 'dsc-node-list' },\n analysis.components.map((component) => h('li', { key: String(component.index) },\n `${t('wfComponentLabel')} ${component.index}(${component.size} ${t('wfNodes')})${component.groups.length > 0 ? `[${component.groups.slice(0, 3).join('+')}]` : ''}`,\n )),\n )\n : h('div', { className: 'dsc-meta' }, t('wfExtractEmpty')),\n h('div', { className: 'dsc-extract-modes' },\n modes.map((entry) => h('label', { key: entry.mode, className: 'dsc-mode' },\n h('input', {\n type: 'radio',\n name: 'extract-mode',\n checked: state.mode === entry.mode,\n onChange: () => onUpdate({ ...state, mode: entry.mode }),\n }),\n h('span', { className: 'dsc-mode-label' }, entry.label),\n h('span', { className: 'dsc-hint' }, entry.hint),\n )),\n ),\n state.error !== null ? h(ErrorNote, { t, message: state.error }) : null,\n h('div', { className: 'dsc-row' },\n h('button', { className: 'dsc-btn', disabled: analysis.components.length === 0, onClick: () => void onRun(state) }, t('wfExtractRun')),\n h('button', { className: 'dsc-btn', onClick: onClose }, t('wfCancel')),\n ),\n ),\n )\n}\n\n/** Read-only inspection of a ComfyUI-side saved workflow: node list + JSON. */\nfunction WorkflowView(props: { t: ComfyUIPanelProps['t']; file: string; graph: Record<string, unknown>; onBack: () => void }): ReturnType<typeof h> {\n const nodes = Array.isArray(props.graph.nodes)\n ? (props.graph.nodes as Array<Record<string, unknown>>).filter((node) => node.mode !== 4 && typeof node.type === 'string' && node.type !== '')\n : []\n const json = JSON.stringify(props.graph, null, 2)\n return h('div', { className: 'dsc-view' },\n h('div', { className: 'dsc-view-head' },\n h('span', { className: 'dsc-wf-name' }, props.file),\n h('button', { className: 'dsc-btn', onClick: props.onBack }, props.t('wfViewBack')),\n ),\n h('div', { className: 'dsc-view-label' }, `${props.t('wfViewNodes')} (${nodes.length})`),\n nodes.length === 0\n ? h('div', { className: 'dsc-meta' }, props.t('wfViewEmpty'))\n : h('ul', { className: 'dsc-node-list' }, nodes.map((node) => h('li', { key: String(node.id) }, `${String(node.id)} · ${String(node.type)}`))),\n h('div', { className: 'dsc-view-label' }, props.t('wfViewJson')),\n h('textarea', { className: 'dsc-textarea dsc-textarea--json dsc-textarea--view', readOnly: true, value: json }),\n )\n}\n\n/** Tab 2: asset preview — thumbnails of everything the plugin generated. */\nfunction AssetsTab({ t, onPreview }: { t: ComfyUIPanelProps['t']; onPreview: (images: string[], kinds: Array<'image' | 'video' | 'audio' | 'other'>, index: number) => void }): ReturnType<typeof h> {\n const [assets, setAssets] = useState<AssetEntry[] | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [filter, setFilter] = useState(() => panelStore.getAssetFilter())\n\n const load = async (): Promise<void> => {\n try {\n const data = await getJson<{ assets: AssetEntry[] }>('/comfyui/assets')\n setAssets(data.assets)\n setError(null)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n }\n }\n\n useEffect(() => {\n let cancelled = false\n void getJson<{ assets: AssetEntry[] }>('/comfyui/assets').then((data) => {\n if (!cancelled) setAssets(data.assets)\n }).catch((cause: unknown) => {\n if (!cancelled) setError(cause instanceof Error ? cause.message : String(cause))\n })\n return () => {\n cancelled = true\n }\n }, [])\n\n if (error !== null) return h('div', null, h(ErrorNote, { t, message: error }))\n if (assets === null) return h('div', { className: 'dsc-meta' }, '…')\n\n const names = [...new Set(assets.map((asset) => asset.workflowName ?? ''))]\n const visible = filter === '' ? assets : assets.filter((asset) => (asset.workflowName ?? '') === filter)\n // Every media item in the visible grid, in display order, for the lightbox\n // sequence (videos/audio included so clicking a thumbnail can play it).\n const previewItems = visible.flatMap((asset) => asset.media.map((item) => ({ url: item.url, kind: item.kind })))\n const openAsset = (asset: AssetEntry): void => {\n const first = asset.media[0]\n const index = first !== undefined ? previewItems.findIndex((item) => item.url === first.url) : 0\n onPreview(previewItems.map((item) => item.url), previewItems.map((item) => item.kind), index < 0 ? 0 : index)\n }\n\n return h('div', null,\n h('div', { className: 'dsc-toolbar' },\n h('select', { className: 'dsc-input dsc-input--inline', value: filter, onChange: (event: { target: { value: string } }) => setFilter(event.target.value) },\n h('option', { value: '' }, t('assetAll')),\n names.map((name) => h('option', { key: name, value: name }, name === '' ? '—' : name)),\n ),\n h('button', { className: 'dsc-btn', onClick: () => void load() }, t('refresh')),\n ),\n visible.length === 0\n ? h('div', { className: 'dsc-meta' }, t('assetEmpty'))\n : h('div', { className: 'dsc-assets-grid' }, visible.map((asset) => h(AssetThumb, { key: asset.promptId, asset, t, onClick: () => openAsset(asset) }))),\n )\n}\n\nfunction AssetThumb(props: { asset: AssetEntry; t: ComfyUIPanelProps['t']; onClick: () => void }): ReturnType<typeof h> {\n const first = props.asset.media[0]\n const [broken, setBroken] = useState(false)\n if (first === undefined || broken) {\n return h('div', { className: 'dsc-asset dsc-asset--empty', onClick: props.onClick },\n h('div', null, props.t('assetGone')),\n h('div', { className: 'dsc-meta' }, props.asset.workflowName ?? '—'),\n )\n }\n return h('div', { className: 'dsc-asset', onClick: props.onClick },\n first.kind === 'video'\n ? h('video', { src: first.url, controls: true, preload: 'metadata', onClick: (event: { stopPropagation: () => void }) => event.stopPropagation() })\n : h('img', { src: first.url, alt: first.filename, loading: 'lazy', onError: () => setBroken(true) }),\n h('div', { className: 'dsc-asset-meta' }, props.asset.workflowName ?? '—'),\n )\n}\n\n/**\n * Tab 3: the task center — active tasks (pending / generating) shown as\n * cards with id, status and progress, plus history filtered by the\n * completed / failed / cancelled chips. Polled every 3 seconds.\n */\nfunction QueueTab({ t, onPreview }: { t: ComfyUIPanelProps['t']; onPreview: (images: string[], kinds: Array<'image' | 'video' | 'audio' | 'other'>, index: number) => void }): ReturnType<typeof h> {\n const [filter, setFilter] = useState<JobFilter>('all')\n const [active, setActive] = useState<JobView[] | null>(null)\n const [history, setHistory] = useState<JobView[] | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [busy, setBusy] = useState(false)\n\n const load = async (current: JobFilter): Promise<void> => {\n try {\n const historyStatus = current === 'all' ? 'completed,failed,cancelled' : current\n const [activeData, historyData] = await Promise.all([\n getJson<JobsView>('/comfyui/jobs?status=pending,in_progress&limit=100'),\n getJson<JobsView>(`/comfyui/jobs?status=${historyStatus}&limit=100`),\n ])\n if (activeData.ok !== true) throw new Error(activeData.error ?? t('queueError'))\n if (historyData.ok !== true) throw new Error(historyData.error ?? t('queueError'))\n // Active queue: earliest submitted first (running on top, later joins append below).\n setActive([...(activeData.jobs ?? [])].sort((a, b) => (a.createTime ?? 0) - (b.createTime ?? 0)))\n setHistory(historyData.jobs)\n setError(null)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n }\n }\n\n useEffect(() => {\n void load(filter)\n const timer = setInterval(() => void load(filter), 3_000)\n return () => clearInterval(timer)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [filter])\n\n const act = async (payload: Record<string, unknown>): Promise<void> => {\n setBusy(true)\n try {\n const data = (await postJson('/comfyui/jobs/actions', payload)) as { ok: boolean; error?: string }\n if (data.ok !== true) throw new Error(data.error ?? 'action failed')\n await load(filter)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setBusy(false)\n }\n }\n\n if (error !== null) return h('div', null, h(ErrorNote, { t, message: error }))\n if (active === null || history === null) return h('div', { className: 'dsc-meta' }, '…')\n\n // Preview image sequence over the history list, plus each job's position in it.\n const historyPreviewUrls = history.map(previewUrlOf)\n const previewImages = historyPreviewUrls.filter((url): url is string => url !== null)\n const previewPrefix: number[] = []\n {\n let acc = 0\n for (const url of historyPreviewUrls) {\n previewPrefix.push(acc)\n if (url !== null) acc += 1\n }\n }\n\n return h('div', { className: 'dsc-list' },\n h('div', { className: 'dsc-queue-actions' },\n h('button', { className: 'dsc-btn', onClick: () => void act({ action: 'clear' }), disabled: busy }, t('jobClearQueue')),\n h('button', { className: 'dsc-btn', onClick: () => void act({ action: 'clearHistory' }), disabled: busy }, t('jobClearHistory')),\n h('button', { className: 'dsc-btn', onClick: () => void act({ action: 'free', unloadModels: true, freeMemory: true }), disabled: busy }, t('jobFree')),\n ),\n h('div', { className: 'dsc-section' },\n h('div', { className: 'dsc-section-head' },\n h('span', { className: 'dsc-section-title' }, `${t('jobActive')} (${active.length})`),\n ),\n active.length === 0\n ? h('div', { className: 'dsc-meta' }, t('queueEmpty'))\n : h('div', { className: 'dsc-list' }, active.map((job) => h(JobRow, { key: job.id, job, t, busy, act }))),\n ),\n h('div', { className: 'dsc-section' },\n h('div', { className: 'dsc-section-head' },\n h('span', { className: 'dsc-section-title' }, `${t('jobFilterLabel')} (${history.length})`),\n h('div', { className: 'dsc-queue-head' },\n JOB_FILTERS.map((item) =>\n h('button', {\n key: item.key,\n className: `dsc-chip${filter === item.key ? ' dsc-chip--active' : ''}`,\n onClick: () => setFilter(item.key),\n disabled: busy,\n }, t(item.label))),\n ),\n ),\n history.length === 0\n ? h('div', { className: 'dsc-meta' }, t('queueEmpty'))\n : h('div', { className: 'dsc-list' }, history.map((job, index) => h(JobRow, {\n key: job.id,\n job,\n t,\n busy,\n act,\n onPreview: historyPreviewUrls[index] !== null && previewImages.length > 0\n ? () => onPreview(previewImages, previewImages.map(() => 'image' as const), previewPrefix[index]!)\n : undefined,\n }))),\n ),\n )\n}\n\nfunction jobBadge(status: JobStatus): string {\n switch (status) {\n case 'in_progress': return 'dsc-badge--info'\n case 'completed': return 'dsc-badge--ok'\n case 'failed': return 'dsc-badge--danger'\n default: return ''\n }\n}\n\nconst STATUS_LABELS: Record<JobStatus, string> = {\n pending: 'jobFilterPending',\n in_progress: 'jobFilterInProgress',\n completed: 'jobFilterCompleted',\n failed: 'jobFilterFailed',\n cancelled: 'jobFilterCancelled',\n}\n\n/**\n * One task card: a compact row with a status badge, task name + short id,\n * duration (and error/progress for in-flight tasks), and a ⋯ menu with\n * per-state actions. Hover highlights the row. Rendered as a component\n * instance (h(JobRow, ...)) so its hooks stay per-card.\n */\nfunction JobRow(props: {\n job: JobView\n t: ComfyUIPanelProps['t']\n busy: boolean\n act: (payload: Record<string, unknown>) => Promise<void>\n onPreview?: () => void\n}): ReturnType<typeof h> {\n const { job, t, busy, act, onPreview } = props\n const [menuOpen, setMenuOpen] = useState(false)\n const menuRef = useRef<HTMLDivElement | null>(null)\n\n useEffect(() => {\n if (!menuOpen) return\n const onDoc = (event: MouseEvent): void => {\n if (menuRef.current !== null && !menuRef.current.contains(event.target as Node)) setMenuOpen(false)\n }\n document.addEventListener('mousedown', onDoc)\n return () => document.removeEventListener('mousedown', onDoc)\n }, [menuOpen])\n\n const running = job.status === 'in_progress'\n const terminal = job.status === 'completed' || job.status === 'failed' || job.status === 'cancelled'\n const pct = job.progress !== null && job.progress !== undefined && job.progress.max > 0\n ? Math.min(100, Math.round((job.progress.value / job.progress.max) * 100))\n : null\n const duration = job.executionStartTime !== null && job.executionEndTime !== null\n ? Math.max(0, Math.round(((job.executionEndTime ?? 0) - (job.executionStartTime ?? 0)) / 1000))\n : null\n const errMsg = job.executionError?.exception_message ?? job.executionError?.message\n const name = job.workflowName ?? job.workflowId\n const preview = previewUrlOf(job)\n const close = (): void => setMenuOpen(false)\n const statusClass = job.status === 'failed' ? ' dsc-job-item--failed' : job.status === 'cancelled' ? ' dsc-job-item--cancelled' : ''\n\n return h('div', { className: `dsc-job-item${statusClass}` },\n preview !== null\n ? h('img', {\n src: preview,\n alt: '',\n loading: 'lazy',\n className: onPreview !== undefined ? 'dsc-job-preview dsc-job-preview--clickable' : 'dsc-job-preview',\n onClick: onPreview,\n })\n : null,\n h('div', { className: 'dsc-job-main' },\n h('div', { className: 'dsc-job-name', title: name ?? undefined },\n name !== null && name !== undefined && name !== '' ? name : '—',\n ),\n h('div', { className: 'dsc-job-mid' },\n running && job.progress !== null && job.progress !== undefined\n ? h('div', { className: 'dsc-progress' },\n h('div', { className: 'dsc-progress-track' },\n h('div', { className: 'dsc-progress-fill', style: { width: `${pct ?? 0}%` } }),\n ),\n h('span', { className: 'dsc-job-progress' },\n `${job.progress.value}/${job.progress.max} · ${pct ?? 0}%`,\n ),\n )\n : null,\n h('div', { className: 'dsc-job-mid-right' },\n h('span', { className: `dsc-badge dsc-badge--status ${jobBadge(job.status)}` }, t(STATUS_LABELS[job.status] ?? job.status)),\n h('div', { ref: menuRef, className: 'dsc-job-menu' },\n h('button', {\n className: 'dsc-job-menu-btn',\n 'aria-label': t('jobMore'),\n onClick: () => setMenuOpen(!menuOpen),\n }, '⋯'),\n menuOpen ? h('div', { className: 'dsc-job-menu-pop' },\n job.status === 'pending'\n ? h('button', { onClick: () => { void act({ action: 'delete', ids: [job.id] }); close() } }, t('jobDelete'))\n : null,\n running\n ? h('button', { onClick: () => { void act({ action: 'interrupt', promptId: job.id }); close() } }, t('jobInterrupt'))\n : null,\n terminal\n ? h('button', { onClick: () => { void act({ action: 'deleteHistory', ids: [job.id] }); close() } }, t('jobDelete'))\n : null,\n terminal\n ? h('button', { onClick: () => { void act({ action: 'rerun', jobId: job.id }); close() } }, t('jobRerun'))\n : null,\n terminal\n ? h('button', { onClick: () => { panelStore.setAssetFilter(name ?? ''); panelStore.setTab('assets'); close() } }, t('jobViewAssets'))\n : null,\n ) : null,\n ),\n ),\n ),\n h('div', { className: 'dsc-job-bottom' },\n h('span', { className: 'dsc-job-duration' }, `${t('jobDuration')} ${duration ?? 0}s`),\n errMsg !== undefined && errMsg !== null ? h('span', { className: 'dsc-job-error', title: errMsg }, errMsg) : null,\n ),\n ),\n )\n}\n","/**\n * dsh-comfyui stylesheet, injected once with plugin ownership. Colors come\n * from the host theme tokens (--dsw-alias-*), so the UI follows light/dark.\n */\nconst CSS = `\n/* --- shared primitives --- */\n.dsc-card {\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 8px;\n padding: 10px 12px;\n margin: 4px 0;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n}\n.dsc-card-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }\n.dsc-badge {\n border-radius: 999px; padding: 1px 8px; font-size: 11px;\n background: var(--dsw-alias-bg-layer-1);\n color: var(--dsw-alias-label-secondary);\n}\n.dsc-badge--ok { background: color-mix(in srgb, var(--dsw-alias-state-success-primary) 16%, transparent); }\n.dsc-badge--err { background: color-mix(in srgb, var(--dsw-alias-state-error-primary) 16%, transparent); }\n.dsc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 8px; margin-top: 6px; }\n.dsc-media { border-radius: 6px; overflow: hidden; background: var(--dsw-alias-bg-layer-1); }\n.dsc-media img, .dsc-media video, .dsc-media audio { display: block; width: 100%; max-height: 320px; object-fit: contain; background: #000; }\n.dsc-media audio { height: 44px; }\n.dsc-media-img--clickable { cursor: zoom-in; }\n.dsc-media-other { display: block; padding: 8px 6px; font-size: 12px; color: var(--dsw-alias-label-secondary); word-break: break-all; }\n.dsc-media-meta { display: flex; align-items: center; justify-content: space-between; gap: 6px; padding: 3px 6px; }\n.dsc-media-size { font-size: 11px; color: var(--dsw-alias-label-secondary); white-space: nowrap; }\n.dsc-media-meta a { display: inline; padding: 0; font-size: 11px; color: var(--dsw-alias-label-secondary); text-decoration: none; }\n.dsc-media-meta a:hover { color: var(--dsw-alias-label-primary); }\n.dsc-meta { color: var(--dsw-alias-label-secondary); font-size: 12px; }\n.dsc-err { color: var(--dsw-alias-state-error-primary); font-size: 12px; margin: 4px 0; }\n.dsc-ok { color: var(--dsw-alias-state-success-primary); font-size: 12px; margin: 4px 0; }\n.dsc-form { display: flex; flex-direction: column; gap: 12px; max-width: 460px; }\n.dsc-field label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 4px; color: var(--dsw-alias-label-primary); }\n.dsc-input, .dsc-textarea {\n width: 100%; box-sizing: border-box; padding: 6px 8px; border-radius: 6px;\n border: 1px solid var(--dsw-alias-border-l1);\n background: transparent; color: inherit; font-size: 13px;\n}\nselect.dsc-input { background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); color-scheme: inherit; }\nselect.dsc-input option { background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); }\n.dsc-textarea { min-height: 90px; resize: vertical; font-family: ui-monospace, monospace; }\n.dsc-hint { font-size: 12px; color: var(--dsw-alias-label-secondary); margin-top: 2px; }\n.dsc-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }\n.dsc-btn {\n border: 1px solid var(--dsw-alias-border-l1); border-radius: 6px;\n background: transparent; color: inherit; padding: 5px 12px; font-size: 13px; cursor: pointer;\n}\n.dsc-btn:disabled { opacity: 0.5; cursor: default; }\n.dsc-btn--link { display: inline-block; text-decoration: none; }\n/* --- header action trigger --- */\n.dsc-trigger {\n display: inline-flex; align-items: center; gap: 5px;\n border: 1px solid transparent; background: transparent; color: var(--dsw-alias-label-secondary);\n cursor: pointer; font-size: 13px; padding: 3px 8px; border-radius: 6px;\n white-space: nowrap;\n}\n.dsc-trigger:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-bg-layer-1); border-color: var(--dsw-alias-border-l1); }\n.dsc-trigger[aria-pressed='true'] { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-bg-layer-2); }\n.dsc-trigger-glyph { font-size: 13px; line-height: 1; }\n/* --- panel shell: floating window, percentage-anchored to the page header\n (top) and the composer (bottom), draggable by the header and resizable via\n the corner handle. Follows the host light/dark theme. --- */\n.dsc-panel {\n position: fixed;\n top: var(--dsc-panel-top, 9%);\n right: var(--dsc-panel-right, 1.5%);\n bottom: var(--dsc-panel-bottom, 2%);\n width: var(--dsc-panel-width, 400px);\n max-width: min(92vw, 560px); min-width: 300px;\n z-index: 900;\n display: flex; flex-direction: column;\n background: var(--dsw-alias-bg-layer-1);\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 14px;\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.28), 0 2px 8px rgba(0, 0, 0, 0.12);\n color: var(--dsw-alias-label-primary);\n overflow: hidden;\n user-select: none;\n}\n.dsc-panel--dragging { cursor: grabbing; }\n.dsc-panel-head { display: flex; align-items: center; justify-content: space-between; padding: 10px 12px; border-bottom: 1px solid var(--dsw-alias-border-l1); cursor: grab; touch-action: none; }\n.dsc-panel--dragging .dsc-panel-head { cursor: grabbing; }\n.dsc-panel-resize {\n position: absolute; right: 0; bottom: 0; width: 16px; height: 16px;\n cursor: nwse-resize; touch-action: none;\n background: linear-gradient(135deg, transparent 50%, var(--dsw-alias-label-tertiary) 50%);\n border-bottom-right-radius: 14px;\n opacity: 0.55;\n}\n.dsc-panel-resize:hover { opacity: 1; }\n.dsc-panel-title { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; font-size: 14px; }\n.dsc-panel-close { border: none; background: transparent; color: var(--dsw-alias-label-secondary); cursor: pointer; font-size: 14px; padding: 4px 8px; }\n.dsc-panel-close:hover { color: var(--dsw-alias-label-primary); }\n.dsc-tabs { display: flex; border-bottom: 1px solid var(--dsw-alias-border-l1); }\n.dsc-tab {\n flex: 1; padding: 8px 4px; background: transparent; border: none;\n border-bottom: 2px solid transparent; color: var(--dsw-alias-label-secondary);\n cursor: pointer; font-size: 13px;\n}\n.dsc-tab--active { color: var(--dsw-alias-label-primary); border-bottom-color: var(--dsw-alias-brand-primary); }\n.dsc-panel-body { flex: 1; overflow-y: auto; padding: 10px 12px; }\n.dsc-toolbar { display: flex; gap: 8px; align-items: center; margin-bottom: 8px; flex-wrap: wrap; }\n.dsc-list { display: flex; flex-direction: column; gap: 8px; }\n/* --- workflows tab --- */\n.dsc-wf { border: 1px solid var(--dsw-alias-border-l1); border-radius: 8px; padding: 8px 10px; background: var(--dsw-alias-bg-layer-1); transition: background 0.12s, border-color 0.12s; cursor: pointer; }\n.dsc-wf:hover { background: var(--dsw-alias-bg-layer-2); border-color: var(--dsw-alias-border-l2); }\n.dsc-wf-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }\n.dsc-wf--comfyui { display: flex; align-items: center; gap: 10px; }\n.dsc-wf-col { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }\n.dsc-wf-name { font-weight: 600; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.dsc-wf-desc { color: var(--dsw-alias-label-secondary); font-size: 12px; margin: 2px 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.dsc-wf-updated { color: var(--dsw-alias-label-tertiary); font-size: 11px; margin-top: 4px; }\n.dsc-wf-actions { display: flex; gap: 6px; margin-top: 6px; }\n.dsc-section { margin-top: 14px; }\n.dsc-section-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }\n.dsc-section-title { font-weight: 600; font-size: 13px; }\n.dsc-fold { border: 1px solid var(--dsw-alias-border-l1); border-radius: 10px; margin-top: 10px; overflow: hidden; background: var(--dsw-alias-bg-layer-1); }\n.dsc-fold summary { list-style: none; display: flex; align-items: center; gap: 6px; padding: 8px 10px; cursor: pointer; user-select: none; font-weight: 600; font-size: 13px; }\n.dsc-fold summary::-webkit-details-marker { display: none; }\n.dsc-fold summary::before { content: '▸'; font-size: 11px; color: var(--dsw-alias-label-secondary); transition: transform 0.15s; }\n.dsc-fold[open] summary::before { transform: rotate(90deg); }\n.dsc-fold summary:hover { background: var(--dsw-alias-bg-layer-2); }\n.dsc-fold-body { padding: 0 10px 10px; }\n.dsc-hint { color: var(--dsw-alias-label-secondary); font-size: 11px; margin: 2px 0 6px; white-space: pre-line; }\n.dsc-badge { font-size: 11px; padding: 1px 8px; border-radius: 999px; }\n.dsc-badge--ok { color: var(--dsw-alias-state-success-primary); border: 1px solid var(--dsw-alias-state-success-primary); }\n.dsc-badge--warn { color: var(--dsw-alias-state-warn-primary); border: 1px solid var(--dsw-alias-state-warn-primary); }\n.dsc-view-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }\n.dsc-view-label { font-weight: 600; font-size: 12px; margin: 8px 0 4px; }\n.dsc-node-list { margin: 0; padding-left: 18px; font-size: 12px; color: var(--dsw-alias-label-secondary); max-height: 180px; overflow-y: auto; }\n.dsc-node-list li { margin: 2px 0; }\n.dsc-textarea--view { min-height: 220px; resize: vertical; }\n.dsc-derived { margin: 6px 0; display: flex; flex-direction: column; gap: 4px; }\n.dsc-derived-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 12px; }\n.dsc-derived-name { color: var(--dsw-alias-label-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.dsc-dialog { border: 1px solid var(--dsw-alias-border-l1); border-radius: 8px; padding: 10px; }\n.dsc-dialog-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }\n.dsc-extract-modes { display: flex; flex-direction: column; gap: 8px; margin: 10px 0; }\n.dsc-mode { display: flex; flex-direction: column; gap: 2px; border: 1px solid var(--dsw-alias-border-l1); border-radius: 8px; padding: 8px 10px; cursor: pointer; }\n.dsc-mode input { accent-color: var(--dsw-alias-brand-primary); }\n.dsc-mode-label { font-size: 13px; }\n/* --- assets tab --- */\n.dsc-assets-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 8px; }\n.dsc-asset { border: 1px solid var(--dsw-alias-border-l1); border-radius: 8px; overflow: hidden; cursor: pointer; background: var(--dsw-alias-bg-layer-1); }\n.dsc-asset img, .dsc-asset video { width: 100%; height: 110px; object-fit: cover; display: block; background: #000; }\n.dsc-asset--empty {\n height: 110px; padding: 8px; box-sizing: border-box;\n display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 4px;\n font-size: 11px; color: var(--dsw-alias-label-secondary); text-align: center;\n}\n.dsc-asset-meta { padding: 3px 6px; font-size: 11px; color: var(--dsw-alias-label-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.dsc-asset-detail-media { display: flex; flex-direction: column; gap: 8px; margin-bottom: 8px; }\n.dsc-asset-detail-media img, .dsc-asset-detail-media video { width: 100%; max-height: 320px; object-fit: contain; background: #000; border-radius: 8px; }\n.dsc-asset-detail-file { display: flex; align-items: center; justify-content: space-between; gap: 8px; border: 1px solid var(--dsw-alias-border-l1); border-radius: 8px; padding: 6px 8px; }\n.dsc-input--inline { width: auto; }\n/* --- queue tab --- */\n.dsc-queue-head { display: flex; gap: 8px; flex-wrap: wrap; }\n.dsc-queue-item { display: flex; gap: 8px; align-items: center; border: 1px solid var(--dsw-alias-border-l1); border-radius: 8px; padding: 6px 8px; font-size: 12px; flex-wrap: wrap; }\n.dsc-queue-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 180px; }\n.dsc-queue-meta { color: var(--dsw-alias-label-secondary); font-size: 11px; }\n.dsc-queue-tracked { margin-top: 10px; display: flex; flex-direction: column; gap: 4px; }\n.dsc-progress { display: flex; align-items: center; gap: 6px; flex: 1; min-width: 90px; }\n.dsc-progress-track { flex: 1; height: 6px; border-radius: 3px; background: var(--dsw-alias-bg-layer-2); overflow: hidden; }\n.dsc-progress-fill { height: 100%; background: #3b82f6; transition: width 0.4s; }\n.dsc-progress:hover .dsc-progress-fill { background: #2563eb; }\n.dsc-param-upload-wrap { display: flex; align-items: center; gap: 8px; min-width: 0; flex: 1; }\n.dsc-param-upload-wrap select { flex: 1; min-width: 0; }\n.dsc-dropzone { flex: 1; min-width: 120px; border: 1px dashed var(--dsw-alias-border-l2); border-radius: 6px; padding: 5px 10px; font-size: 11px; color: var(--dsw-alias-label-secondary); text-align: center; cursor: pointer; transition: border-color 0.12s, color 0.12s; }\n.dsc-dropzone:hover, .dsc-dropzone--over { border-color: #3b82f6; color: #3b82f6; }\n.dsc-upload-select { position: relative; flex: 1; min-width: 0; }\n.dsc-upload-select-btn { display: flex; align-items: center; gap: 6px; width: 100%; border: 1px solid var(--dsw-alias-border-l1); border-radius: 6px; padding: 3px 8px; background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); cursor: pointer; font-size: 12px; text-align: left; }\n.dsc-upload-select-btn:hover { border-color: var(--dsw-alias-border-l2); }\n.dsc-upload-select-thumb { width: 36px; height: 24px; object-fit: cover; border-radius: 3px; background: var(--dsw-alias-bg-layer-2); flex: none; }\n.dsc-upload-select-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }\n.dsc-upload-select-pop { position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 30; max-height: 220px; overflow-y: auto; border: 1px solid var(--dsw-alias-border-l2); border-radius: 8px; background: var(--dsw-alias-bg-layer-2); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35); padding: 4px; }\n.dsc-upload-select-item { display: flex; align-items: center; gap: 8px; padding: 5px 8px; border-radius: 6px; cursor: pointer; font-size: 12px; color: var(--dsw-alias-label-primary); }\n.dsc-upload-select-item:hover { background: var(--dsw-alias-bg-layer-3); }\n.dsc-upload-dock { margin-top: 14px; border-top: 1px solid var(--dsw-alias-border-l1); padding-top: 10px; display: flex; flex-direction: column; gap: 8px; }\n.dsc-upload-dock-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }\n.dsc-upload-dock-title { font-weight: 600; font-size: 12px; color: var(--dsw-alias-label-primary); }\n.dsc-upload-dock-zone { min-height: 44px; display: flex; align-items: center; justify-content: center; }\n.dsc-upload-list { display: flex; flex-direction: column; gap: 4px; }\n.dsc-upload-item { display: flex; align-items: center; gap: 8px; }\n.dsc-upload-thumb { width: 40px; height: 28px; object-fit: cover; border-radius: 4px; background: var(--dsw-alias-bg-layer-2); flex: none; }\n.dsc-upload-thumb--media { display: inline-flex; align-items: center; justify-content: center; font-size: 14px; }\n.dsc-upload-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; color: var(--dsw-alias-label-primary); }\n.dsc-upload-select-item--active { background: var(--dsw-alias-bg-layer-3); }\n/* --- load area: big preview + picker dialog (ComfyUI LoadImage-like) --- */\n.dsc-loadarea { margin-top: 14px; border-top: 1px solid var(--dsw-alias-border-l1); padding-top: 10px; display: flex; flex-direction: column; gap: 8px; }\n.dsc-loadarea-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }\n.dsc-loadarea-title { font-weight: 600; font-size: 12px; color: var(--dsw-alias-label-primary); }\n.dsc-loadarea-main { display: flex; flex-direction: column; align-items: center; gap: 6px; width: 100%; border: 1px solid var(--dsw-alias-border-l2); border-radius: 10px; padding: 10px; background: var(--dsw-alias-bg-layer-1); cursor: pointer; transition: border-color 0.12s; }\n.dsc-loadarea-main:hover { border-color: #3b82f6; }\n.dsc-loadarea-main:disabled { opacity: 0.6; cursor: default; }\n.dsc-loadarea-img { width: 100%; max-height: 260px; object-fit: contain; border-radius: 8px; background: var(--dsw-alias-bg-layer-2); }\n.dsc-loadarea-empty { display: flex; align-items: center; justify-content: center; height: 120px; width: 100%; border-radius: 8px; background: var(--dsw-alias-bg-layer-2); color: var(--dsw-alias-label-tertiary); font-size: 13px; }\n.dsc-loadarea-name { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; color: var(--dsw-alias-label-primary); }\n/* picker overlay: dims the page, dialog floats in the center */\n.dsc-picker-overlay { position: fixed; inset: 0; z-index: 9990; background: rgba(6, 8, 12, 0.6); display: flex; align-items: center; justify-content: center; padding: 24px; }\n.dsc-picker { position: relative; display: flex; flex-direction: column; width: min(860px, 92vw); height: min(560px, 84vh); background: var(--dsw-alias-bg-layer-1); border: 1px solid var(--dsw-alias-border-l2); border-radius: 12px; box-shadow: 0 16px 56px rgba(0, 0, 0, 0.5); overflow: hidden; }\n.dsc-picker-toast { position: absolute; top: 54px; left: 50%; transform: translateX(-50%); z-index: 5; background: var(--dsw-alias-brand-primary); color: var(--dsw-alias-bg-layer-1); padding: 6px 14px; border-radius: 8px; font-size: 12px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3); pointer-events: none; max-width: 80%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.dsc-picker-bar { display: flex; align-items: center; gap: 4px; padding: 8px 10px; border-bottom: 1px solid var(--dsw-alias-border-l1); flex-wrap: wrap; }\n.dsc-picker-tab { border: 1px solid transparent; border-radius: 6px; padding: 4px 12px; font-size: 12px; cursor: pointer; background: transparent; color: var(--dsw-alias-label-primary); }\n.dsc-picker-tab--active { background: var(--dsw-alias-brand-primary); color: var(--dsw-alias-bg-layer-1); }\n.dsc-picker-tabs { display: flex; gap: 4px; }\n.dsc-picker-type { flex: none; border: 1px solid var(--dsw-alias-border-l1); border-radius: 6px; padding: 3px 8px; font-size: 12px; background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); }\n.dsc-picker-upload { margin: 0 auto; flex: none; max-width: 200px; min-height: 32px; display: flex; align-items: center; justify-content: center; padding: 0 12px; font-size: 12px; white-space: nowrap; }\n.dsc-picker-empty { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; color: var(--dsw-alias-label-tertiary); font-size: 13px; }\n.dsc-picker-grid { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; padding: 12px; display: flex; gap: 10px; align-items: flex-start; }\n.dsc-picker-col { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 10px; }\n.dsc-picker-card { display: flex; flex-direction: column; gap: 4px; min-width: 0; border: 1px solid var(--dsw-alias-border-l1); border-radius: 8px; padding: 6px; background: var(--dsw-alias-bg-layer-2); cursor: pointer; text-align: left; }\n.dsc-picker-card:hover { border-color: #3b82f6; }\n.dsc-picker-card--active { border-color: var(--dsw-alias-brand-primary); box-shadow: 0 0 0 1px var(--dsw-alias-brand-primary); }\n.dsc-picker-thumb { width: 100%; height: auto; object-fit: contain; border-radius: 6px; background: var(--dsw-alias-bg-layer-1); }\n.dsc-picker-thumb--media { display: flex; align-items: center; justify-content: center; height: 100px; font-size: 22px; }\n.dsc-picker-name { font-size: 11px; color: var(--dsw-alias-label-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n/* --- workflow tags: filter bar, chips, editor --- */\n.dsc-tag-filter { display: flex; flex-wrap: wrap; gap: 6px; padding: 6px 0 2px; }\n.dsc-tag-chip { border: 1px solid var(--dsw-alias-border-l1); border-radius: 999px; padding: 2px 10px; font-size: 12px; cursor: pointer; background: transparent; color: var(--dsw-alias-label-primary); }\n.dsc-tag-chip--active { background: var(--dsw-alias-brand-primary); border-color: var(--dsw-alias-brand-primary); color: var(--dsw-alias-bg-layer-1); }\n.dsc-tag-chip--mini { font-size: 11px; padding: 1px 8px; cursor: default; border: 1px solid var(--dsw-alias-brand-primary); color: var(--dsw-alias-brand-primary); background: color-mix(in srgb, var(--dsw-alias-brand-primary) 10%, transparent); }\n.dsc-wf-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 3px; }\n.dsc-wf-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; min-width: 0; }\n.dsc-wf-top .dsc-wf-tags { margin-top: 0; flex: none; justify-content: flex-end; }\n.dsc-tag-editor { display: flex; flex-direction: column; gap: 6px; }\n.dsc-tag-row { display: flex; flex-wrap: wrap; gap: 6px; }\n.dsc-tag-input { max-width: 260px; }\n.dsc-chip { border: 1px solid var(--dsw-alias-border-l1); border-radius: 999px; padding: 2px 10px; font-size: 12px; cursor: pointer; background: transparent; color: var(--dsw-alias-label-primary); }\n.dsc-chip--active { background: var(--dsw-alias-brand-primary); border-color: var(--dsw-alias-brand-primary); color: var(--dsw-alias-bg-layer-1); }\n.dsc-badge--info { background: var(--dsw-alias-brand-primary); color: var(--dsw-alias-bg-layer-1); }\n.dsc-badge--danger { background: var(--dsw-alias-state-error-primary); color: #fff; }\n.dsc-queue-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }\n.dsc-btn { border: 1px solid var(--dsw-alias-border-l1); border-radius: 6px; padding: 2px 8px; font-size: 12px; cursor: pointer; background: transparent; color: var(--dsw-alias-label-primary); }\n.dsc-btn--sm { padding: 1px 6px; font-size: 11px; }\n.dsc-btn:disabled { opacity: 0.5; cursor: default; }\n.dsc-job-item { display: flex; align-items: center; gap: 10px; border: 1px solid var(--dsw-alias-border-l1); border-radius: 8px; padding: 7px 10px; background: var(--dsw-alias-bg-layer-1); transition: background 0.12s, border-color 0.12s; }\n.dsc-job-item:hover { background: var(--dsw-alias-bg-layer-2); border-color: var(--dsw-alias-border-l2); }\n.dsc-job-item--failed { border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary) 55%, transparent); }\n.dsc-job-item--cancelled { border-color: var(--dsw-alias-border-l2); opacity: 0.85; }\n.dsc-badge--status { flex: none; font-weight: 600; }\n.dsc-job-preview { width: 56px; height: 56px; flex: none; border-radius: 6px; object-fit: cover; border: 1px solid var(--dsw-alias-border-l1); background: var(--dsw-alias-bg-layer-2); }\n.dsc-job-preview--clickable { cursor: zoom-in; }\n/* --- lightbox: floating local panel, no full-screen dim --- */\n.dsc-lightbox { position: fixed; inset: 0; z-index: 9999; background: transparent; display: flex; align-items: center; justify-content: center; }\n.dsc-lightbox-body { position: relative; display: flex; flex-direction: column; align-items: center; gap: 10px; width: 90vw; padding: 12px 12px 10px; background: rgba(12, 14, 18, 0.88); border: 1px solid var(--dsw-alias-border-l2); border-radius: 14px; box-shadow: 0 12px 48px rgba(0, 0, 0, 0.45); }\n.dsc-lightbox-img { width: 100%; height: 80vh; object-fit: contain; border-radius: 8px; }\n.dsc-lightbox-media { max-width: 100%; max-height: 80vh; border-radius: 8px; }\n.dsc-lightbox-meta { display: flex; align-items: center; gap: 14px; color: rgba(255, 255, 255, 0.75); font-size: 12px; }\n.dsc-lightbox-download { border: 1px solid rgba(255, 255, 255, 0.35); border-radius: 999px; padding: 5px 16px; color: #fff; font-size: 12px; text-decoration: none; display: inline-block; }\n.dsc-lightbox-download:hover { background: rgba(255, 255, 255, 0.12); }\n.dsc-lightbox-close { position: absolute; top: clamp(4px, 0.6vw, 14px); right: clamp(4px, 0.6vw, 14px); z-index: 3; width: clamp(28px, 2.2vw, 48px); height: clamp(28px, 2.2vw, 48px); border-radius: 50%; border: 1px solid rgba(255, 255, 255, 0.35); background: transparent; color: #fff; font-size: clamp(13px, 1.1vw, 22px); line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center; }\n.dsc-lightbox-close:hover { background: rgba(255, 255, 255, 0.12); }\n.dsc-lightbox-nav { position: absolute; top: 0; bottom: 0; z-index: 2; width: clamp(64px, 7vw, 128px); display: flex; align-items: center; background: transparent; border: none; color: #fff; font-size: clamp(38px, 3.4vw, 84px); line-height: 1; cursor: pointer; opacity: 0.6; padding: 0; }\n.dsc-lightbox-nav:hover { opacity: 1; color: var(--dsw-alias-brand-primary); background: rgba(255, 255, 255, 0.06); }\n.dsc-lightbox-nav--prev { left: 0; justify-content: flex-start; padding-left: clamp(14px, 1.8vw, 36px); }\n.dsc-lightbox-nav--next { right: 0; justify-content: flex-end; padding-right: clamp(14px, 1.8vw, 36px); }\n.dsc-job-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }\n.dsc-job-name { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dsw-alias-label-primary); }\n.dsc-job-mid { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; }\n.dsc-job-mid-right { display: flex; align-items: center; gap: 6px; flex: none; margin-left: auto; }\n.dsc-job-bottom { display: flex; align-items: center; gap: 8px; font-size: 11px; color: var(--dsw-alias-label-secondary); min-width: 0; }\n.dsc-job-duration { flex: none; }\n.dsc-job-progress { color: #3b82f6; font-variant-numeric: tabular-nums; }\n.dsc-job-menu { position: relative; flex: none; }\n.dsc-job-menu-btn { border: none; background: transparent; color: var(--dsw-alias-label-secondary); font-size: 15px; line-height: 1; padding: 3px 7px; border-radius: 6px; cursor: pointer; }\n.dsc-job-menu-btn:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-bg-layer-2); }\n.dsc-job-menu-pop { position: absolute; right: 0; top: calc(100% + 4px); z-index: 950; min-width: 128px; padding: 4px; display: flex; flex-direction: column; gap: 2px; background: var(--dsw-alias-bg-layer-2); border: 1px solid var(--dsw-alias-border-l2); border-radius: 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25); }\n.dsc-job-menu-pop button { border: none; background: transparent; color: var(--dsw-alias-label-primary); text-align: left; font-size: 13px; padding: 6px 10px; border-radius: 6px; cursor: pointer; }\n.dsc-job-menu-pop button:hover { background: var(--dsw-alias-bg-layer-3); }\n.dsc-job-error { color: var(--dsw-alias-state-error-primary); font-size: 11px; margin-left: auto; flex: 1; min-width: 0; text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n/* --- parameter editor --- */\n.dsc-params { display: flex; flex-direction: column; gap: 8px; }\n.dsc-param-row { display: flex; flex-direction: column; gap: 6px; border: 1px solid var(--dsw-alias-border-l1); border-radius: 8px; padding: 6px 8px; }\n.dsc-param-fields { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }\n.dsc-param-default { min-width: 0; }\n.dsc-param-meta { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }\n.dsc-param-random { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--dsw-alias-label-secondary); cursor: pointer; }\n.dsc-param-advanced { display: flex; flex-direction: column; gap: 8px; border: 1px dashed var(--dsw-alias-border-l2); border-radius: 8px; padding: 8px; }\n`\n\n/** Inject the stylesheet once (idempotent), owned by this plugin for HMR. */\nexport function injectStyles(): void {\n if (typeof document === 'undefined') return\n if (document.getElementById('dsh-comfyui-styles') !== null) return\n const style = document.createElement('style')\n style.id = 'dsh-comfyui-styles'\n style.setAttribute('data-plugin', 'dsh-comfyui')\n style.textContent = CSS\n document.head.append(style)\n}\n","/**\n * dsh-comfyui client half: registers the comfyui_run tool card and the\n * ComfyUI settings page. Registered through slots.inject so contributions\n * wait on the real slot declarations and unwind with this plugin's fiber.\n */\nimport { createElement as h } from 'react'\nimport { makeT, getLang } from './i18n.ts'\nimport { ComfyUICard, type ComfyUICardProps } from './card.tsx'\nimport { ComfyUISettings, type ComfyUISettingsProps } from './settings.tsx'\nimport { ComfyUIPanel, type ComfyUIPanelProps } from './panel.tsx'\nimport { ComfyUITrigger, type ComfyUITriggerProps } from './trigger.tsx'\nimport { injectStyles } from './styles.ts'\n\nexport const name = 'dsh-comfyui'\nexport const inject = ['slots']\n\ninterface SlotsService {\n inject(slot: string, register: () => unknown): void\n register(meta: Record<string, unknown>, component: unknown): unknown\n}\n\ninterface ComfyUIClientContext {\n effect(callback: () => unknown, label?: string): void\n slots: SlotsService\n}\n\nexport function apply(ctx: ComfyUIClientContext): void {\n // Plugin-local i18n: language comes from localStorage (settings page), not\n // the host locale, so zh/en switching works without a host change.\n const t = makeT(getLang())\n ctx.effect(() => injectStyles(), 'dsh-comfyui: styles')\n\n ctx.slots.inject('tool.call.toolview', () => ctx.slots.register(\n { name: 'tool.call.toolview', key: 'comfyui_run' },\n (props: unknown) => h(ComfyUICard, { t, ...((props ?? {}) as Record<string, unknown>) } as unknown as ComfyUICardProps),\n ))\n\n ctx.slots.inject('tool.call.toolview', () => ctx.slots.register(\n { name: 'tool.call.toolview', key: 'comfyui_workflow' },\n (props: unknown) => h(ComfyUICard, { t, ...((props ?? {}) as Record<string, unknown>) } as unknown as ComfyUICardProps),\n ))\n\n ctx.slots.inject('settings.section', () => ctx.slots.register(\n { name: 'settings.section', id: 'comfyui', order: 30, label: () => t('settingsTitle') },\n (props: unknown) => h(ComfyUISettings, { t, ...((props ?? {}) as Record<string, unknown>) } as unknown as ComfyUISettingsProps),\n ))\n\n ctx.slots.inject('shell.overlay', () => ctx.slots.register(\n { name: 'shell.overlay', id: 'comfyui.panel', order: 20, label: () => t('panelTitle') },\n (props: unknown) => h(ComfyUIPanel, { t, ...((props ?? {}) as Record<string, unknown>) } as unknown as ComfyUIPanelProps),\n ))\n\n ctx.slots.inject('conversation.session.header.actions', () => ctx.slots.register(\n { name: 'conversation.session.header.actions', id: 'comfyui', order: 100, label: () => t('panelTitle') },\n (props: unknown) => h(ComfyUITrigger, { t, ...((props ?? {}) as Record<string, unknown>) } as unknown as ComfyUITriggerProps),\n ))\n}\n"],"mappings":"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"}
|