@dickpy/dsh-imagegen 1.2.2 → 1.3.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/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["css","Button","css","Button","Pill","css","css","css","css"],"sources":["../src/protocol.ts","../src/client/api.ts","../src/client/controller.ts","../src/client/locales.ts","../src/client/helpers.ts","../src/client/TemplateLibrary.tsx","../src/image-models.ts","../src/client/ImageGenPanel.tsx","../src/client/mount.tsx","../src/client/sidebar-entry.ts","../src/client/settings-form.ts","../src/client/SettingsCard.tsx","../src/client/settings-scope.ts","../src/client/image-toolview.tsx","../src/client/index.ts"],"sourcesContent":["/**\n * Wire contract shared by the host and client halves of dsh-imagegen: the\n * settings namespace, the route paths, and the generate payload/result shapes.\n * Pure types + constants 鈥?safe for the client bundle to inline.\n */\n\n/** Settings namespace this plugin owns (host settings seam + bridge). */\nexport const IMAGEGEN_SETTINGS_NAMESPACE = 'dsh-imagegen'\n\n/** Published package version shared by the host updater and the client UI. */\nexport const PLUGIN_VERSION = '1.2.2'\n\n/** Same-origin route family (loopback-only, mirroring the dsh-ssh fence). */\nexport const SETTINGS_API = {\n describe: '/api/dsh-imagegen/settings/describe',\n mutate: '/api/dsh-imagegen/settings/mutate',\n} as const\n\n/** The image-generation proxy route. */\nexport const GENERATE_API = '/api/dsh-imagegen/generate'\n\n/** Host-mediated OpenAI-compatible prompt enhancement endpoints. */\nexport const PROMPT_ENHANCE_API = {\n models: '/api/dsh-imagegen/prompt-enhance/models',\n enhance: '/api/dsh-imagegen/prompt-enhance',\n} as const\n\n/** Host-mediated candidate discovery for the configured image API. */\nexport const IMAGE_MODEL_API = {\n models: '/api/dsh-imagegen/image-models',\n} as const\n\n/** Host-resident generation queue endpoints. */\nexport const TASK_API = {\n submit: '/api/dsh-imagegen/tasks/submit',\n list: '/api/dsh-imagegen/tasks/list',\n cancel: '/api/dsh-imagegen/tasks/cancel',\n retry: '/api/dsh-imagegen/tasks/retry',\n} as const\n\n/** Host-mediated GitHub Release update routes. */\nexport const UPDATE_API = {\n check: '/api/dsh-imagegen/update/check',\n apply: '/api/dsh-imagegen/update/apply',\n} as const\n\n/**\n * Same-origin route family for the host-persisted generation history. Images\n * live as files under ~/.dsh/dsh-imagegen/images/ and are served back through\n * the `image` prefix route, so list responses carry metadata only (never\n * base64) and the browser loads thumbnails/previews lazily.\n */\nexport const HISTORY_API = {\n list: '/api/dsh-imagegen/history/list',\n append: '/api/dsh-imagegen/history/append',\n remove: '/api/dsh-imagegen/history/remove',\n clear: '/api/dsh-imagegen/history/clear',\n image: '/api/dsh-imagegen/history/image',\n} as const\n\n/**\n * Same-origin route family for the user-curated gallery (favorites). Entries\n * reuse the history wire shape and persist under ~/.dsh/dsh-imagegen/gallery/;\n * unlike history there is no size cap 鈥?the user adds images on purpose.\n */\nexport const GALLERY_API = {\n list: '/api/dsh-imagegen/gallery/list',\n append: '/api/dsh-imagegen/gallery/append',\n remove: '/api/dsh-imagegen/gallery/remove',\n clear: '/api/dsh-imagegen/gallery/clear',\n tags: '/api/dsh-imagegen/gallery/tags',\n image: '/api/dsh-imagegen/gallery/image',\n} as const\n\n/** Maximum number of history entries retained host-side (oldest evicted). */\nexport const HISTORY_MAX = 50\n\n/**\n * Same-origin route family for the bundled prompt-template library\n * (awesome-gpt-image-2 mirror). The case list ships inside the package and is\n * served by the host; reference images are proxied through the `image` prefix\n * route and cached on disk so repeated views never hit the network again.\n */\nexport const TEMPLATES_API = {\n list: '/api/dsh-imagegen/templates/list',\n refresh: '/api/dsh-imagegen/templates/refresh',\n image: '/api/dsh-imagegen/templates/image',\n} as const\n\n/** One prompt-library case as the browser consumes it. */\nexport interface TemplateCase {\n /** Upstream case number (stable across refreshes). */\n id: number\n /** Short case title. */\n title: string\n /** Full reusable prompt text. */\n prompt: string\n /** English category name (grouping key). */\n category: string\n /** Chinese category display name. */\n categoryZh: string\n /** Style tags. */\n styles: string[]\n /** Scene tags. */\n scenes: string[]\n /** Original author handle, e.g. @vista8. */\n sourceLabel: string\n /** Original author link. */\n sourceUrl: string\n /** awesome-gpt-image-2 repo anchor link. */\n githubUrl: string\n /** Reference-image file name served through the image route ('' when none). */\n image: string\n /** Whether the source gallery featured the case. */\n featured: boolean\n}\n\n/** Template-library list payload. */\nexport interface TemplateListResult {\n cases: TemplateCase[]\n total: number\n /** Where the served list came from. */\n origin: 'bundled' | 'refreshed'\n /** Upstream repository the library mirrors. */\n repository: string\n /** ISO time of the last successful refresh / bundle snapshot. */\n fetchedAt: string\n}\n\n/** Template-library refresh outcome. */\nexport interface TemplateRefreshResult {\n total: number\n fetchedAt: string\n}\n\n/** Generation modes. */\nexport type GenerateMode = 'text' | 'edit'\n\n/** A client 鈫?host generate request (what the panel collects). */\nexport interface GenerateRequest {\n /** text-to-image (images/generations) or image-to-image (images/edits). */\n mode: GenerateMode\n /** Upstream model name, e.g. gpt-image-2. */\n model: string\n /** The prompt. Upstream providers may impose their own length limits. */\n prompt: string\n /** Canvas size as an aspect ratio: 'auto' or e.g. '1:1' / '16:9' / '21:9'.\n * The host maps it onto each model's own vocabulary (aspect_ratio for Grok,\n * the closest pixel size for OpenAI-compatible endpoints). */\n size: string\n /** Clarity tier: 'auto' | '1k' | '2k' | '4k'. The host maps it onto the\n * model's own vocabulary (resolution for Grok, quality for OpenAI). */\n quality: string\n /** Number of images, 1-4. */\n n: number\n /**\n * Passthrough detail parameter: '' (omit), 'standard', or 'high'. Some\n * gpt-image-2 gateways expose it; official OpenAI endpoints reject unknown\n * parameters, so the UI defaults to '' (omit).\n */\n detail: string\n /** Reference image as a data URL (edit mode only). */\n image?: string\n /** Original reference-image name, retained in the history entry. */\n refName?: string\n}\n\n/** One generated image, normalized host-side to base64 so the browser never\n * has to fetch the upstream (no CORS, no key exposure). */\nexport interface GeneratedImage {\n /** Raw base64 payload (no data: prefix). */\n b64: string\n /** MIME type of the payload, e.g. image/png. */\n mime: string\n /** Upstream revised prompt, when provided. */\n revisedPrompt?: string\n}\n\n/** Successful generate outcome. */\nexport interface GenerateResult {\n images: GeneratedImage[]\n /** Updated host-persisted history, when returned by the generate route. */\n history?: HistoryEntry[]\n /** Persistence failure after images were successfully generated. */\n historyError?: string\n}\n\nexport type GenerationTaskStatus = 'queued' | 'running' | 'completed' | 'failed' | 'cancelled'\n\nexport interface GenerationTask {\n id: string\n request: GenerateRequest\n status: GenerationTaskStatus\n createdAt: number\n startedAt?: number\n finishedAt?: number\n result?: GenerateResult\n error?: string\n}\n\n/** GitHub Release update information shown by the client. */\nexport interface UpdateInfo {\n currentVersion: string\n latestVersion: string\n updateAvailable: boolean\n releaseUrl: string\n publishedAt?: string\n}\n\n/** One history image reference as the browser consumes it (a served URL). */\nexport interface HistoryImageRef {\n /** Same-origin URL: `${HISTORY_API.image}/<file>`. */\n url: string\n /** MIME type, e.g. image/png. */\n mime: string\n /** Upstream revised prompt, when provided. */\n revisedPrompt?: string\n}\n\n/** A saved generation as the browser consumes it (metadata + served images). */\nexport interface HistoryEntry {\n id: string\n createdAt: number\n mode: GenerateMode\n model: string\n prompt: string\n size: string\n quality: string\n detail: string\n n: number\n images: HistoryImageRef[]\n /** Reference-image filename (edit mode), kept for display only. */\n refName?: string\n /** User-managed gallery labels (unused by history entries). */\n tags?: string[]\n}\n\n/** A history entry the client submits for persistence (images still carry base64). */\nexport interface HistoryEntryInput {\n id: string\n createdAt: number\n mode: GenerateMode\n model: string\n prompt: string\n size: string\n quality: string\n detail: string\n n: number\n images: GeneratedImage[]\n refName?: string\n}\n","/**\n * Browser-side API client for the /api/dsh-imagegen route family. The only\n * data access path the panel uses — plain fetch, same origin.\n */\n\nimport { GALLERY_API, GENERATE_API, HISTORY_API, PROMPT_ENHANCE_API, TASK_API, TEMPLATES_API, UPDATE_API, type GenerateRequest, type GenerateResult, type GenerationTask, type HistoryEntry, type HistoryEntryInput, type TemplateListResult, type TemplateRefreshResult, type UpdateInfo } from '../protocol.ts'\n\n/** Error carrying the route's JSON error message. */\nexport class ImageGenApiError extends Error {\n /** Stable wire code from the host. */\n readonly code: string\n\n constructor(message: string, code = 'generate-failed') {\n super(message)\n this.name = 'ImageGenApiError'\n this.code = code\n }\n}\n\n/** Parse the { ok, ... } envelope or throw an ImageGenApiError. */\nasync function readEnvelope<T>(response: Response): Promise<T> {\n let body: unknown\n try {\n body = await response.json()\n } catch {\n throw new ImageGenApiError(`HTTP ${response.status}: invalid JSON response`)\n }\n if (body === null || typeof body !== 'object') {\n throw new ImageGenApiError(`HTTP ${response.status}: malformed response`)\n }\n const record = body as { ok?: unknown; message?: unknown; code?: unknown }\n if (record.ok !== true) {\n throw new ImageGenApiError(\n typeof record.message === 'string' ? record.message : `HTTP ${response.status}`,\n typeof record.code === 'string' ? record.code : 'generate-failed',\n )\n }\n return body as T\n}\n\n/** The browser half's data entry point. */\nexport class ImageGenApi {\n /** Ask the host to check the latest stable GitHub Release. */\n async updateCheck(): Promise<UpdateInfo> {\n const response = await fetch(UPDATE_API.check, { method: 'POST' })\n const body = await readEnvelope<{ ok: true; update: UpdateInfo }>(response)\n return body.update\n }\n\n /** Ask the host to install a previously discovered Release. */\n async updateApply(version: string): Promise<{ updatedVersion: string; restartRequired: boolean }> {\n const response = await fetch(UPDATE_API.apply, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ version }),\n })\n const body = await readEnvelope<{ ok: true; updatedVersion: string; restartRequired: boolean }>(response)\n return { updatedVersion: body.updatedVersion, restartRequired: body.restartRequired }\n }\n\n /** Forward one generate request to the host proxy. */\n async generate(request: GenerateRequest): Promise<GenerateResult> {\n const response = await fetch(GENERATE_API, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(request),\n })\n const body = await readEnvelope<{ ok: true; images: GenerateResult['images']; history?: HistoryEntry[]; historyError?: string }>(response)\n return {\n images: body.images,\n ...body.history === undefined ? {} : { history: body.history },\n ...body.historyError === undefined ? {} : { historyError: body.historyError },\n }\n }\n\n /** Ask the configured chat model to expand a concise image prompt. */\n async enhancePrompt(prompt: string): Promise<string> {\n const response = await fetch(PROMPT_ENHANCE_API.enhance, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ prompt }),\n })\n const body = await readEnvelope<{ ok: true; prompt: string }>(response)\n return body.prompt\n }\n\n async taskSubmit(request: GenerateRequest): Promise<GenerationTask> {\n const response = await fetch(TASK_API.submit, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(request) })\n return (await readEnvelope<{ ok: true; task: GenerationTask }>(response)).task\n }\n\n async taskList(): Promise<GenerationTask[]> {\n const response = await fetch(TASK_API.list, { method: 'POST' })\n return (await readEnvelope<{ ok: true; tasks: GenerationTask[] }>(response)).tasks\n }\n\n async taskCancel(id: string): Promise<GenerationTask> {\n const response = await fetch(TASK_API.cancel, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ id }) })\n return (await readEnvelope<{ ok: true; task: GenerationTask }>(response)).task\n }\n\n async taskRetry(id: string): Promise<GenerationTask> {\n const response = await fetch(TASK_API.retry, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ id }) })\n return (await readEnvelope<{ ok: true; task: GenerationTask }>(response)).task\n }\n\n /** List the host-persisted history (newest first). */\n async historyList(): Promise<HistoryEntry[]> {\n const response = await fetch(HISTORY_API.list, { method: 'POST' })\n const body = await readEnvelope<{ ok: true; entries: HistoryEntry[] }>(response)\n return body.entries\n }\n\n /** Remove one history entry by id. */\n async historyRemove(id: string): Promise<HistoryEntry[]> {\n const response = await fetch(HISTORY_API.remove, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id }),\n })\n const body = await readEnvelope<{ ok: true; entries: HistoryEntry[] }>(response)\n return body.entries\n }\n\n /** Clear the entire history. */\n async historyClear(): Promise<HistoryEntry[]> {\n const response = await fetch(HISTORY_API.clear, { method: 'POST' })\n const body = await readEnvelope<{ ok: true; entries: HistoryEntry[] }>(response)\n return body.entries\n }\n\n /** List the host-persisted gallery (newest first). */\n async galleryList(): Promise<HistoryEntry[]> {\n const response = await fetch(GALLERY_API.list, { method: 'POST' })\n const body = await readEnvelope<{ ok: true; entries: HistoryEntry[] }>(response)\n return body.entries\n }\n\n /** Append one image to the gallery. The host assigns the id and skips the\n * append when a content-identical image is already in the gallery. */\n async galleryAppend(entry: HistoryEntryInput): Promise<{ entries: HistoryEntry[]; added: boolean }> {\n const response = await fetch(GALLERY_API.append, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ entry }),\n })\n const body = await readEnvelope<{ ok: true; entries: HistoryEntry[]; added: boolean }>(response)\n return { entries: body.entries, added: body.added }\n }\n\n /** Remove one gallery entry by id. */\n async galleryRemove(id: string): Promise<HistoryEntry[]> {\n const response = await fetch(GALLERY_API.remove, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id }),\n })\n const body = await readEnvelope<{ ok: true; entries: HistoryEntry[] }>(response)\n return body.entries\n }\n\n /** Clear the entire gallery. */\n async galleryClear(): Promise<HistoryEntry[]> {\n const response = await fetch(GALLERY_API.clear, { method: 'POST' })\n const body = await readEnvelope<{ ok: true; entries: HistoryEntry[] }>(response)\n return body.entries\n }\n\n async gallerySetTags(id: string, tags: string[]): Promise<HistoryEntry[]> {\n const response = await fetch(GALLERY_API.tags, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ id, tags }) })\n return (await readEnvelope<{ ok: true; entries: HistoryEntry[] }>(response)).entries\n }\n\n /** Fetch the prompt-template library (bundled snapshot or refreshed copy). */\n async templatesList(): Promise<TemplateListResult> {\n const response = await fetch(TEMPLATES_API.list, { method: 'POST' })\n const body = await readEnvelope<TemplateListResult & { ok: true }>(response)\n return {\n cases: body.cases,\n total: body.total,\n origin: body.origin,\n repository: body.repository,\n fetchedAt: body.fetchedAt,\n }\n }\n\n /** Re-download the template library from the upstream mirror (host-side). */\n async templatesRefresh(): Promise<TemplateRefreshResult> {\n const response = await fetch(TEMPLATES_API.refresh, { method: 'POST' })\n const body = await readEnvelope<TemplateRefreshResult & { ok: true }>(response)\n return { total: body.total, fetchedAt: body.fetchedAt }\n }\n}\n","/**\n * Image-gen panel controller: the single owner of the panel's open/closed\n * state. Framework-free so the DOM mounts and the React panel share one tiny\n * subscription surface. The state lives only for the browser session.\n */\n\n/** Immutable controller snapshot for UI subscriptions. */\nexport interface ImageGenControllerSnapshot {\n panelOpen: boolean\n}\n\n/** The panel state owner the sidebar entry toggles and the view renders from. */\nexport class ImageGenController {\n private panelOpen = false\n private listeners = new Set<() => void>()\n\n getSnapshot(): ImageGenControllerSnapshot {\n return { panelOpen: this.panelOpen }\n }\n\n subscribe(fn: () => void): () => void {\n this.listeners.add(fn)\n return () => { this.listeners.delete(fn) }\n }\n\n open(): void {\n if (this.panelOpen) return\n this.panelOpen = true\n this.notify()\n }\n\n close(): void {\n if (!this.panelOpen) return\n this.panelOpen = false\n this.notify()\n }\n\n toggle(): void {\n if (this.panelOpen) this.close()\n else this.open()\n }\n\n private notify(): void {\n for (const fn of [...this.listeners]) fn()\n }\n}\n","/**\n * dsh-imagegen surface copy: zh is the key source, en mirrors every key.\n */\n\nexport const zh = {\n 'entry.label': 'AI 生图',\n 'entry.tooltip': 'AI 生图面板(gpt-image-2 / grok-imagine-image)',\n 'panel.title': 'AI 生图',\n 'panel.githubTip': '觉得好用或有建议?欢迎来 GitHub 提 issues、点个 star 支持一下!',\n // mode\n 'mode.text': '文生图',\n 'mode.edit': '图生图',\n // prompt\n 'prompt.placeholder': '描述你想要的画面,例如:一只戴着宇航员头盔的橘猫,在月球上举起望远镜,水彩风格,柔和光线…',\n 'prompt.required': '请输入提示词',\n 'prompt.count': '{count}',\n 'prompt.enhance': '增强',\n 'prompt.enhancing': '增强中…',\n 'prompt.enhanceHint': '使用已配置的对话模型扩写提示词',\n 'prompt.configTitle': '请先配置提示词增强模型',\n 'prompt.configHint': '已打开设置。进入「插件 → AI 生图」,填写或复用 API 地址和密钥,选择对话模型并保存。',\n 'tasks.title': '生成任务',\n 'tasks.queued': '排队中',\n 'tasks.running': '生成中',\n 'tasks.completed': '已完成',\n 'tasks.failed': '失败',\n 'tasks.cancelled': '已取消',\n 'tasks.cancel': '取消',\n 'tasks.retry': '重试',\n // parameters\n 'params.size': '尺寸',\n 'params.quality': '清晰度',\n 'params.count': '生成数量',\n 'params.detail': '细节',\n 'size.auto': '自动',\n 'size.square': '1:1 方图',\n 'size.portrait34': '3:4 标准竖图',\n 'size.landscape43': '4:3 标准横图',\n 'size.portrait916': '9:16 竖屏',\n 'size.portrait23': '2:3 竖图',\n 'size.landscape32': '3:2 横图',\n 'size.wide169': '16:9 宽屏',\n 'size.ultrawide21': '21:9 超宽屏',\n 'quality.auto': '自动',\n 'quality.1k': '1K',\n 'quality.2k': '2K',\n 'quality.4k': '4K',\n 'count.one': '1 张',\n 'count.two': '2 张',\n 'count.three': '3 张',\n 'count.four': '4 张',\n 'detail.auto': '自动',\n 'detail.standard': '标准',\n 'detail.high': '高清',\n 'detail.hint': '透传参数,部分 gpt-image-2 网关支持;官方接口请保持「自动」',\n // footer\n 'model.label': '模型',\n 'compare.enable': '多模型对比',\n 'compare.models': '参与对比的模型',\n 'compare.title': '多模型结果对比',\n 'compare.fullscreen': '全屏对比',\n 'compare.selectRequired': '请至少选择一个对比模型',\n 'generate': '开始生成',\n 'generating': '生成中…',\n // edit reference image\n 'edit.upload': '点击或拖拽上传参考图片',\n 'edit.uploadHint': 'PNG / JPG / WEBP,不超过 10MB',\n 'edit.change': '更换图片',\n 'edit.remove': '移除',\n 'edit.required': '请先上传参考图片',\n // canvas\n 'canvas.emptyTitle': '开始你的创作',\n 'canvas.emptyHint': '在左侧输入提示词并点击「开始生成」,结果将显示在这里',\n 'canvas.error': '生成失败:{error}',\n 'canvas.generating': '正在生成图片…',\n 'canvas.elapsed': '已用时 {seconds}s',\n 'canvas.images': '本次生成 {count} 张',\n 'download': '下载',\n 'revisedPrompt': '优化提示词:{prompt}',\n // history\n 'history.title': '历史记录',\n 'history.empty': '暂无历史记录,生成图片后会保存在这里',\n 'history.clear': '清空',\n 'history.restore': '恢复',\n 'history.delete': '删除',\n 'history.images': '张',\n 'history.viewing': '历史 · {time}',\n 'history.search': '搜索提示词或模型…',\n 'history.model': '模型筛选',\n 'history.ratio': '比例筛选',\n 'history.allModels': '全部模型',\n 'history.allRatios': '全部比例',\n // gallery\n 'gallery.title': '画廊',\n 'gallery.categories': '分类',\n 'gallery.all': '全部作品',\n 'gallery.gpt': 'gpt-image-2',\n 'gallery.grok': 'grok-imagine-image',\n 'gallery.ratio': '画面比例',\n 'gallery.tags': '标签',\n 'gallery.filterHint': '按生成模式、模型和比例筛选画廊',\n 'gallery.count': '· 共 {count} 幅',\n 'gallery.viewMode': '视图模式',\n 'gallery.masonry': '瀑布流',\n 'gallery.grid': '整齐网格',\n 'gallery.sort': '排序',\n 'gallery.newest': '最新发布',\n 'gallery.oldest': '最早发布',\n 'gallery.untitled': '未命名作品',\n 'gallery.search': '搜索作品或模型…',\n 'gallery.tagsPlaceholder': '标签,用逗号分隔',\n 'gallery.tagsApply': '添加标签',\n 'gallery.editTags': '编辑标签',\n 'gallery.tagsEditShort': '编辑',\n 'gallery.tagsSave': '保存',\n 'gallery.tagsCancel': '取消',\n 'gallery.selected': '已选 {count} 项',\n 'gallery.selectionDone': '完成选择',\n 'gallery.selectionClear': '取消选择',\n 'gallery.downloadSelected': '下载所选',\n 'gallery.exportJson': '导出 JSON',\n 'gallery.select': '选择作品',\n 'gallery.add': '加入画廊',\n 'gallery.added': '已加入画廊',\n 'gallery.already': '已在画廊中',\n 'gallery.delete': '移出画廊',\n 'gallery.clear': '清空画廊',\n 'gallery.empty': '画廊还是空的,把喜欢的图片加入进来吧',\n 'gallery.viewing': '画廊 · {time}',\n // preview\n 'preview.title': '图片预览',\n 'preview.open': '点击预览',\n 'preview.close': '关闭',\n 'preview.prev': '上一张',\n 'preview.next': '下一张',\n 'preview.index': '{index} / {total}',\n 'preview.zoomControls': '图片缩放控制',\n 'preview.zoomIn': '放大',\n 'preview.zoomOut': '缩小',\n 'preview.zoomReset': '重置缩放',\n 'preview.zoomLevel': '{percent}%',\n 'preview.copyPrompt': '复制提示词',\n 'preview.copied': '已复制',\n 'preview.addToEdit': '添加到图生图',\n // config banner\n 'config.missing': '尚未配置 API:请前往「设置 → 插件 → 可配置」为 AI 生图填写 api_url 与 api_key。',\n 'config.generationTitle': '请先配置生图 API',\n 'config.generationHint': '已自动打开 DSH「设置 → 插件 → AI 生图」。填写生图 API 地址与 API 密钥,保存后即可开始生成。',\n 'config.enhancementTitle': '请先配置提示词增强模型',\n 'config.enhancementHint': '已自动打开 DSH「设置 → 插件 → AI 生图」。填写或复用对话 API 地址和密钥,选择对话模型并保存。',\n 'config.disabledTitle': 'AI 生图插件已停用',\n 'config.disabledHint': '已自动打开 DSH「设置 → 插件 → AI 生图」。开启「启用插件」后即可生成图片。',\n 'config.configured': '已连接 {url}',\n 'config.disabled': '插件已停用,请在设置中重新启用。',\n 'connection.connected': '已连接',\n 'connection.disconnected': '未连接',\n // plugin update\n 'update.available': '检测到新版本:{version}',\n 'update.install': '在线更新',\n 'update.installing': '更新中…',\n 'update.success': '已更新到 {version},请重启 DSH',\n 'update.failed': '更新失败,请重试',\n 'update.release': '查看 Release',\n // settings card\n 'settings.title': 'AI 生图(dsh-imagegen)',\n 'settings.description': '配置图像生成 API 地址与密钥',\n 'settings.currentVersion': '当前版本',\n 'settings.apiUrl': 'API 地址(api_url)',\n 'settings.apiUrlHint': 'OpenAI 兼容接口基址,如 https://api.openai.com/v1;将自动拼接 /images/generations 与 /images/edits',\n 'settings.apiKey': 'API 密钥(api_key)',\n 'settings.apiKeyHint': 'Bearer 密钥,明文存于本机设置文档;界面只显示是否已设置',\n 'settings.apiKeySet': '已保存密钥;输入新值可更换,点击「清除」可删除',\n 'settings.apiKeyClear': '清除',\n 'settings.imageModelsTitle': '生图模型',\n 'settings.imageModelsHint': '保存 API 地址和密钥后检测候选模型;请只选择实际支持生图的项。',\n 'settings.imageModels': '允许使用的生图模型',\n 'settings.imageModelsManualHint': '一行一个模型;API 未提供 /models 时可手动填写。面板和 Agent 只能使用此列表。',\n 'settings.imageModelsFetch': '检测可用模型',\n 'settings.imageModelsLoading': '检测中…',\n 'settings.imageModelsCandidates': '检测到的候选模型(勾选后保存)',\n 'settings.addModel': '+ 手动添加',\n 'settings.cancelAddModel': '收起添加',\n 'settings.addModelPlaceholder': '输入模型名称,例如 qwen-image',\n 'settings.addModelConfirm': '添加',\n 'settings.removeModel': '移除模型',\n 'settings.optional': '可选',\n 'settings.moreOptions': '更多设置',\n 'settings.promptEnhanceTitle': '提示词增强模型',\n 'settings.promptEnhanceHint': '用于将简短描述扩写为更完整的生图提示词;留空的地址和密钥会复用生图配置。',\n 'settings.promptApiUrl': '对话 API 地址(可选)',\n 'settings.promptApiUrlHint': 'OpenAI 兼容基址;留空则复用图像 API 地址。',\n 'settings.promptApiKey': '对话 API 密钥(可选)',\n 'settings.promptApiKeyHint': '留空则复用图像 API 密钥。',\n 'settings.promptModel': '对话模型',\n 'settings.promptModelHint': '选择或填写支持 /chat/completions 的模型。',\n 'settings.promptModelDetectionHint': '默认复用生图 API;检测后点选一个模型即可。',\n 'settings.promptModelsFetch': '获取可用模型',\n 'settings.promptModelsLoading': '正在获取…',\n 'settings.promptModelsSelect': '选择一个模型',\n 'settings.promptModelsCandidates': '检测到的候选对话模型',\n 'settings.addPromptModelPlaceholder': '输入对话模型名称,例如 gpt-4.1-mini',\n 'settings.promptApiAdvanced': '使用独立对话 API(可选)',\n 'settings.announceToAgent': '向 Agent 播报本插件',\n 'settings.announceToAgentHint': '开启后,本插件的存在与能力会写入每个 Agent 的系统提示词',\n 'settings.allowAgentImageGeneration': '允许 Agent 调用生图',\n 'settings.allowAgentImageGenerationHint': '默认开启。关闭后,Agent 无法提交、查询或取消生图任务;侧边栏工作台不受影响。',\n 'settings.enabled': '启用插件',\n 'settings.enabledHint': '关闭后生图面板不可用(设置卡片始终可用)',\n 'settings.save': '保存',\n 'settings.saving': '保存中…',\n 'settings.discard': '放弃修改',\n 'settings.unsaved': '有未保存的修改',\n 'settings.saveFailed': '保存失败,请重试',\n 'settings.readOnly': '当前设置文档为只读,无法保存。',\n 'settings.notExposed': '设置命名空间不可用:本部署未提供该插件的设置服务。',\n 'settings.expand': '展开',\n 'settings.collapse': '收起',\n 'settings.inherit': '继承',\n 'settings.on': '开',\n 'settings.off': '关',\n 'settings.overridden': '已覆盖',\n 'settings.reset': '重置',\n 'settings.invalidNumber': '请输入有效数字',\n // template library\n 'templates.open': '模板库',\n 'templates.title': '提示词模板库',\n 'templates.meta': '共 {count} 个模板 · {origin}',\n 'templates.origin.bundled': '内置快照',\n 'templates.origin.refreshed': '在线刷新',\n 'templates.search': '搜索模板标题或提示词…',\n 'templates.all': '全部',\n 'templates.close': '关闭',\n 'templates.back': '返回列表',\n 'templates.use': '使用此提示词',\n 'templates.copy': '复制提示词',\n 'templates.copied': '已复制',\n 'templates.refresh': '刷新模板库',\n 'templates.refreshing': '刷新中…',\n 'templates.refreshed': '已刷新,共 {count} 个模板',\n 'templates.refreshFailed': '刷新失败:{error}',\n 'templates.cacheAll': '缓存全部图片',\n 'templates.cacheAllHint': '通过本机代理把全部参考图缓存到本地磁盘,之后离线也能浏览',\n 'templates.caching': '缓存中 {done}/{total}…',\n 'templates.cached': '图片已全部缓存',\n 'templates.empty': '没有匹配的模板',\n 'templates.loading': '正在加载模板库…',\n 'templates.loadFailed': '模板库加载失败:{error}',\n 'templates.retry': '重试',\n 'templates.attribution': '模板与图片来自 awesome-gpt-image-2 项目,作者链接见各模板详情',\n 'templates.source': '来源:vibeui.top',\n 'templates.featured': '精选',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n 'entry.label': 'AI Image',\n 'entry.tooltip': 'AI image generation studio (gpt-image-2 / grok-imagine-image)',\n 'panel.title': 'AI Image',\n 'panel.githubTip': 'Like it or have suggestions? Head to GitHub to open issues and star us!',\n 'mode.text': 'Text to Image',\n 'mode.edit': 'Image to Image',\n 'prompt.placeholder': 'Describe the picture you want, e.g. an orange cat in an astronaut helmet raising a telescope on the moon, watercolor style, soft light…',\n 'prompt.required': 'Enter a prompt first',\n 'prompt.count': '{count}',\n 'prompt.enhance': 'Enhance',\n 'prompt.enhancing': 'Enhancing…',\n 'prompt.enhanceHint': 'Expand the prompt with the configured chat model',\n 'prompt.configTitle': 'Configure a prompt enhancement model first',\n 'prompt.configHint': 'Settings has opened. Go to Plugins → AI Image, configure or reuse an API URL and key, choose a chat model, then save.',\n 'tasks.title': 'Generation tasks',\n 'tasks.queued': 'Queued',\n 'tasks.running': 'Generating',\n 'tasks.completed': 'Completed',\n 'tasks.failed': 'Failed',\n 'tasks.cancelled': 'Cancelled',\n 'tasks.cancel': 'Cancel',\n 'tasks.retry': 'Retry',\n 'params.size': 'Size',\n 'params.quality': 'Quality',\n 'params.count': 'Count',\n 'params.detail': 'Detail',\n 'size.auto': 'Auto',\n 'size.square': '1:1 Square',\n 'size.portrait34': '3:4 Portrait',\n 'size.landscape43': '4:3 Landscape',\n 'size.portrait916': '9:16 Vertical',\n 'size.portrait23': '2:3 Portrait',\n 'size.landscape32': '3:2 Landscape',\n 'size.wide169': '16:9 Widescreen',\n 'size.ultrawide21': '21:9 Ultrawide',\n 'quality.auto': 'Auto',\n 'quality.1k': '1K',\n 'quality.2k': '2K',\n 'quality.4k': '4K',\n 'count.one': '1',\n 'count.two': '2',\n 'count.three': '3',\n 'count.four': '4',\n 'detail.auto': 'Auto',\n 'detail.standard': 'Standard',\n 'detail.high': 'High',\n 'detail.hint': 'Passthrough parameter supported by some gpt-image-2 gateways; keep \"Auto\" for official endpoints',\n 'model.label': 'Model',\n 'compare.enable': 'Multi-model comparison',\n 'compare.models': 'Models to compare',\n 'compare.title': 'Multi-model comparison',\n 'compare.fullscreen': 'Fullscreen comparison',\n 'compare.selectRequired': 'Select at least one model',\n 'generate': 'Generate',\n 'generating': 'Generating…',\n 'edit.upload': 'Click or drag to upload a reference image',\n 'edit.uploadHint': 'PNG / JPG / WEBP, up to 10MB',\n 'edit.change': 'Change image',\n 'edit.remove': 'Remove',\n 'edit.required': 'Upload a reference image first',\n 'canvas.emptyTitle': 'Start creating',\n 'canvas.emptyHint': 'Enter a prompt on the left and click \"Generate\"; results appear here',\n 'canvas.error': 'Generation failed: {error}',\n 'canvas.generating': 'Generating images…',\n 'canvas.elapsed': 'Elapsed {seconds}s',\n 'canvas.images': '{count} image(s) generated',\n 'download': 'Download',\n 'revisedPrompt': 'Refined prompt: {prompt}',\n 'history.title': 'History',\n 'history.empty': 'No history yet — generations will be saved here',\n 'history.clear': 'Clear',\n 'history.restore': 'Restore',\n 'history.delete': 'Delete',\n 'history.images': 'images',\n 'history.viewing': 'History · {time}',\n 'history.search': 'Search prompt or model…',\n 'history.model': 'Model filter',\n 'history.ratio': 'Ratio filter',\n 'history.allModels': 'All models',\n 'history.allRatios': 'All ratios',\n 'gallery.title': 'Gallery',\n 'gallery.categories': 'Categories',\n 'gallery.all': 'All works',\n 'gallery.gpt': 'gpt-image-2',\n 'gallery.grok': 'grok-imagine-image',\n 'gallery.ratio': 'Aspect ratio',\n 'gallery.tags': 'Tags',\n 'gallery.filterHint': 'Filter by mode, model, and aspect ratio',\n 'gallery.count': '· {count} works',\n 'gallery.viewMode': 'View mode',\n 'gallery.masonry': 'Masonry',\n 'gallery.grid': 'Grid',\n 'gallery.sort': 'Sort',\n 'gallery.newest': 'Newest',\n 'gallery.oldest': 'Oldest',\n 'gallery.untitled': 'Untitled work',\n 'gallery.search': 'Search works or models…',\n 'gallery.tagsPlaceholder': 'Tags, comma separated',\n 'gallery.tagsApply': 'Add tags',\n 'gallery.editTags': 'Edit tags',\n 'gallery.tagsEditShort': 'Edit',\n 'gallery.tagsSave': 'Save',\n 'gallery.tagsCancel': 'Cancel',\n 'gallery.selected': '{count} selected',\n 'gallery.selectionDone': 'Done selecting',\n 'gallery.selectionClear': 'Clear selection',\n 'gallery.downloadSelected': 'Download selected',\n 'gallery.exportJson': 'Export JSON',\n 'gallery.select': 'Select work',\n 'gallery.add': 'Add to gallery',\n 'gallery.added': 'Added to gallery',\n 'gallery.already': 'Already in gallery',\n 'gallery.delete': 'Remove',\n 'gallery.clear': 'Clear gallery',\n 'gallery.empty': 'The gallery is empty — add images you like here',\n 'gallery.viewing': 'Gallery · {time}',\n 'preview.title': 'Image preview',\n 'preview.open': 'Click to preview',\n 'preview.close': 'Close',\n 'preview.prev': 'Previous',\n 'preview.next': 'Next',\n 'preview.index': '{index} / {total}',\n 'preview.zoomControls': 'Image zoom controls',\n 'preview.zoomIn': 'Zoom in',\n 'preview.zoomOut': 'Zoom out',\n 'preview.zoomReset': 'Reset zoom',\n 'preview.zoomLevel': '{percent}%',\n 'preview.copyPrompt': 'Copy prompt',\n 'preview.copied': 'Copied',\n 'preview.addToEdit': 'Add to image to image',\n 'config.missing': 'API not configured: open \"Settings → Plugins → Configurable\" and fill in api_url and api_key for AI Image.',\n 'config.generationTitle': 'Configure the image API first',\n 'config.generationHint': 'DSH Settings → Plugins → AI Image has opened. Enter the image API URL and API key, then save before generating.',\n 'config.enhancementTitle': 'Configure a prompt enhancement model first',\n 'config.enhancementHint': 'DSH Settings → Plugins → AI Image has opened. Configure or reuse a chat API URL and key, choose a chat model, then save.',\n 'config.disabledTitle': 'The AI Image plugin is disabled',\n 'config.disabledHint': 'DSH Settings → Plugins → AI Image has opened. Enable the plugin, then generate images.',\n 'config.configured': 'Connected to {url}',\n 'config.disabled': 'The plugin is disabled — re-enable it in Settings.',\n 'connection.connected': 'Connected',\n 'connection.disconnected': 'Disconnected',\n 'update.available': 'A new version is available: {version}',\n 'update.install': 'Update online',\n 'update.installing': 'Updating…',\n 'update.success': 'Updated to {version}; restart DSH to load it',\n 'update.failed': 'Update failed; please try again',\n 'update.release': 'View Release',\n 'settings.title': 'AI Image (dsh-imagegen)',\n 'settings.description': 'Configure the image generation API endpoint and key',\n 'settings.currentVersion': 'Current version',\n 'settings.apiUrl': 'API URL (api_url)',\n 'settings.apiUrlHint': 'OpenAI-compatible base URL, e.g. https://api.openai.com/v1; /images/generations and /images/edits are appended',\n 'settings.apiKey': 'API Key (api_key)',\n 'settings.apiKeyHint': 'Bearer key, stored in plaintext in the local settings document; the UI only shows whether it is set',\n 'settings.apiKeySet': 'A key is stored; type a new value to replace it, or click \"Clear\" to remove it',\n 'settings.apiKeyClear': 'Clear',\n 'settings.imageModelsTitle': 'Image generation models',\n 'settings.imageModelsHint': 'Save the API URL and key, then detect candidate models. Select only models that actually support image generation.',\n 'settings.imageModels': 'Allowed image models',\n 'settings.imageModelsManualHint': 'One model per line. Add models manually when the API does not provide /models. The panel and Agent can use only this list.',\n 'settings.imageModelsFetch': 'Detect available models',\n 'settings.imageModelsLoading': 'Detecting…',\n 'settings.imageModelsCandidates': 'Detected candidate models (select, then save)',\n 'settings.addModel': '+ Add manually',\n 'settings.cancelAddModel': 'Hide add',\n 'settings.addModelPlaceholder': 'Enter a model name, e.g. qwen-image',\n 'settings.addModelConfirm': 'Add',\n 'settings.removeModel': 'Remove model',\n 'settings.optional': 'Optional',\n 'settings.moreOptions': 'More settings',\n 'settings.promptEnhanceTitle': 'Prompt enhancement model',\n 'settings.promptEnhanceHint': 'Expands short requests into complete image prompts. Blank URL and key reuse the image API configuration.',\n 'settings.promptApiUrl': 'Chat API URL (optional)',\n 'settings.promptApiUrlHint': 'OpenAI-compatible base URL. Leave blank to reuse the image API URL.',\n 'settings.promptApiKey': 'Chat API key (optional)',\n 'settings.promptApiKeyHint': 'Leave blank to reuse the image API key.',\n 'settings.promptModel': 'Chat model',\n 'settings.promptModelHint': 'Select or enter a model supporting /chat/completions.',\n 'settings.promptModelDetectionHint': 'Uses the image API by default. Detect and select one model.',\n 'settings.promptModelsFetch': 'Fetch available models',\n 'settings.promptModelsLoading': 'Fetching…',\n 'settings.promptModelsSelect': 'Select a model',\n 'settings.promptModelsCandidates': 'Detected chat model candidates',\n 'settings.addPromptModelPlaceholder': 'Enter a chat model name, e.g. gpt-4.1-mini',\n 'settings.promptApiAdvanced': 'Use a separate chat API (optional)',\n 'settings.announceToAgent': 'Announce this plugin to agents',\n 'settings.announceToAgentHint': 'When on, the plugin presence and capabilities are written into every agent system prompt',\n 'settings.allowAgentImageGeneration': 'Allow agents to generate images',\n 'settings.allowAgentImageGenerationHint': 'On by default. When off, agents cannot submit, query, or cancel image tasks; the sidebar studio remains available.',\n 'settings.enabled': 'Enable plugin',\n 'settings.enabledHint': 'When off, the generation studio is unavailable (this card stays available)',\n 'settings.save': 'Save',\n 'settings.saving': 'Saving…',\n 'settings.discard': 'Discard',\n 'settings.unsaved': 'Unsaved changes',\n 'settings.saveFailed': 'Save failed, please retry',\n 'settings.readOnly': 'The settings document is read-only; saving is disabled.',\n 'settings.notExposed': 'Settings namespace unavailable: this deployment does not serve this plugin\\'s settings.',\n 'settings.expand': 'Expand',\n 'settings.collapse': 'Collapse',\n 'settings.inherit': 'Inherit',\n 'settings.on': 'On',\n 'settings.off': 'Off',\n 'settings.overridden': 'Overridden',\n 'settings.reset': 'Reset',\n 'settings.invalidNumber': 'Enter a valid number',\n // template library\n 'templates.open': 'Templates',\n 'templates.title': 'Prompt Template Library',\n 'templates.meta': '{count} templates · {origin}',\n 'templates.origin.bundled': 'bundled snapshot',\n 'templates.origin.refreshed': 'refreshed online',\n 'templates.search': 'Search template titles or prompts…',\n 'templates.all': 'All',\n 'templates.close': 'Close',\n 'templates.back': 'Back to list',\n 'templates.use': 'Use this prompt',\n 'templates.copy': 'Copy prompt',\n 'templates.copied': 'Copied',\n 'templates.refresh': 'Refresh library',\n 'templates.refreshing': 'Refreshing…',\n 'templates.refreshed': 'Refreshed — {count} templates',\n 'templates.refreshFailed': 'Refresh failed: {error}',\n 'templates.cacheAll': 'Cache all images',\n 'templates.cacheAllHint': 'Mirror every reference image to local disk through the host proxy, for offline browsing',\n 'templates.caching': 'Caching {done}/{total}…',\n 'templates.cached': 'All images cached',\n 'templates.empty': 'No matching templates',\n 'templates.loading': 'Loading the template library…',\n 'templates.loadFailed': 'Failed to load the library: {error}',\n 'templates.retry': 'Retry',\n 'templates.attribution': 'Templates and images come from the awesome-gpt-image-2 project; author links are on each template',\n 'templates.source': 'Source: vibeui.top',\n 'templates.featured': 'Featured',\n}\n\n/** Locale key union. */\nexport type ImageGenKey = keyof typeof zh\n","/**\n * Shared panel helpers: the active-dictionary pick (document-language based,\n * dsh-ssh precedent) bound to the dsh-imagegen interpolator, plus a small\n * error-message extractor. All copy stays in the locale dictionaries.\n */\n\nimport { en, zh, type ImageGenKey } from './locales.ts'\n\n/** Template values accepted by the interpolator. */\nexport type TranslateValues = Record<string, string | number>\n\n/** Active dictionary, picked by the document language at call time. */\nexport function dictionary(): Record<string, string> {\n const lang = typeof document !== 'undefined' ? document.documentElement.lang : 'zh'\n return lang.toLowerCase().startsWith('en') ? { ...en } : { ...zh }\n}\n\n/** Translate a key with optional {name} template params (current language). */\nexport function tt(key: ImageGenKey, values?: TranslateValues): string {\n const text = dictionary()[key] ?? key\n if (values === undefined) return text\n let rendered = text\n for (const [name, value] of Object.entries(values)) {\n rendered = rendered.replaceAll(`{${name}}`, String(value))\n }\n return rendered\n}\n\n/** Human-readable error text from an unknown thrown value. */\nexport function errorMessage(error: unknown): string {\n if (error instanceof Error) return error.message\n return String(error)\n}\n","/**\n * Prompt-template library overlay: a searchable, category-filtered gallery of\n * the bundled awesome-gpt-image-2 cases. The case list is served by the host\n * (bundled snapshot, optionally refreshed online); reference images load\n * lazily through the host's caching proxy, so browsing progressively mirrors\n * the gallery onto the local disk. Picking a template hands its prompt back\n * to the studio form.\n */\n\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport { Button } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { ImageGenApi } from './api.ts'\nimport { errorMessage, tt } from './helpers.ts'\nimport { TEMPLATES_API, type TemplateCase, type TemplateListResult } from '../protocol.ts'\nimport css from './templates.module.css'\n\n/** Concurrent image downloads while caching the whole gallery offline. */\nconst CACHE_ALL_CONCURRENCY = 4\n\n/** Same-origin URL of one case's reference image (host caching proxy). */\nfunction imageUrlOf(item: TemplateCase): string {\n return `${TEMPLATES_API.image}/${encodeURIComponent(item.image)}`\n}\n\n/** A card thumbnail that falls back to a placeholder when the proxy 404s. */\nfunction TemplateThumb(props: { item: TemplateCase }) {\n const [failed, setFailed] = useState(false)\n if (props.item.image === '' || failed) {\n return (\n <span className={css.thumbPlaceholder} aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" width=\"26\" height=\"26\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"3\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><path d=\"M21 15l-5-5L5 21\"/></svg>\n </span>\n )\n }\n return (\n <img\n className={css.thumb}\n src={imageUrlOf(props.item)}\n alt={props.item.title}\n loading=\"lazy\"\n onError={() => { setFailed(true) }}\n />\n )\n}\n\n/** The template-library modal. Rendered through a portal above the studio. */\nexport function TemplateLibrary(props: {\n api: ImageGenApi\n /** Hand a picked prompt back to the studio form and close the library. */\n onUse: (prompt: string) => void\n onClose: () => void\n}) {\n const { api, onUse, onClose } = props\n const [list, setList] = useState<TemplateListResult | null>(null)\n const [loadError, setLoadError] = useState<string | null>(null)\n const [query, setQuery] = useState('')\n const [category, setCategory] = useState('')\n const [selected, setSelected] = useState<TemplateCase | null>(null)\n const [copied, setCopied] = useState(false)\n const [refreshing, setRefreshing] = useState(false)\n const [notice, setNotice] = useState<string | null>(null)\n const [cacheAll, setCacheAll] = useState<{ running: boolean; done: number; total: number }>({ running: false, done: 0, total: 0 })\n const searchRef = useRef<HTMLInputElement>(null)\n const load = (): void => {\n api.templatesList()\n .then(result => { setList(result); setLoadError(null) })\n .catch(caught => { setLoadError(errorMessage(caught)) })\n }\n\n // Load once on open; focus the search box for immediate typing.\n useEffect(() => {\n load()\n searchRef.current?.focus()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const categories = useMemo(() => {\n if (list === null) return [] as Array<{ key: string; label: string; count: number }>\n const counts = new Map<string, { label: string; count: number }>()\n for (const item of list.cases) {\n const entry = counts.get(item.category) ?? { label: item.categoryZh || item.category, count: 0 }\n entry.count += 1\n counts.set(item.category, entry)\n }\n return [...counts.entries()].map(([key, value]) => ({ key, label: value.label, count: value.count }))\n }, [list])\n\n const filtered = useMemo(() => {\n if (list === null) return [] as TemplateCase[]\n const needle = query.trim().toLowerCase()\n return list.cases.filter(item => {\n if (category !== '' && item.category !== category) return false\n if (needle === '') return true\n return item.title.toLowerCase().includes(needle)\n || item.prompt.toLowerCase().includes(needle)\n || item.sourceLabel.toLowerCase().includes(needle)\n })\n }, [list, query, category])\n\n // Escape backs out of the detail view first, then closes the modal.\n useEffect(() => {\n const onKey = (event: KeyboardEvent): void => {\n if (event.key !== 'Escape') return\n event.stopPropagation()\n if (selected !== null) setSelected(null)\n else onClose()\n }\n window.addEventListener('keydown', onKey, true)\n return () => window.removeEventListener('keydown', onKey, true)\n }, [selected, onClose])\n\n const refresh = async (): Promise<void> => {\n if (refreshing) return\n setRefreshing(true)\n setNotice(null)\n try {\n const result = await api.templatesRefresh()\n const reloaded = await api.templatesList()\n setList(reloaded)\n setLoadError(null)\n setNotice(tt('templates.refreshed', { count: result.total }))\n } catch (caught) {\n setNotice(tt('templates.refreshFailed', { error: errorMessage(caught) }))\n } finally {\n setRefreshing(false)\n }\n }\n\n /** Mirror every reference image through the host cache (offline browsing). */\n const cacheAllImages = async (): Promise<void> => {\n if (cacheAll.running || list === null) return\n const files = [...new Set(list.cases.map(item => item.image).filter(name => name !== ''))]\n setCacheAll({ running: true, done: 0, total: files.length })\n let index = 0\n const worker = async (): Promise<void> => {\n while (index < files.length) {\n const file = files[index]!\n index += 1\n try {\n await fetch(`${TEMPLATES_API.image}/${encodeURIComponent(file)}`)\n } catch { /* individual failures are retried on the next run */ }\n setCacheAll(current => ({ ...current, done: current.done + 1 }))\n }\n }\n await Promise.all(Array.from({ length: CACHE_ALL_CONCURRENCY }, () => worker()))\n setCacheAll({ running: false, done: files.length, total: files.length })\n }\n\n const copyPrompt = async (text: string): Promise<void> => {\n try {\n if (navigator.clipboard?.writeText !== undefined) {\n await navigator.clipboard.writeText(text)\n } else {\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 const copiedOk = document.execCommand('copy')\n textarea.remove()\n if (!copiedOk) throw new Error('copy failed')\n }\n setCopied(true)\n window.setTimeout(() => { setCopied(false) }, 1800)\n } catch {\n setCopied(false)\n }\n }\n\n const originLabel = list === null ? '' : tt(list.origin === 'refreshed' ? 'templates.origin.refreshed' : 'templates.origin.bundled')\n\n return createPortal(\n <div className={css.overlay} role=\"dialog\" aria-modal=\"true\" aria-label={tt('templates.title')} onClick={onClose}>\n <section className={css.shell} onClick={(event) => { event.stopPropagation() }}>\n <header className={css.header}>\n <span className={css.heading}>\n <h3 className={css.title}>{tt('templates.title')}</h3>\n {list !== null ? (\n <span className={css.meta}>{tt('templates.meta', { count: list.total, origin: originLabel })}</span>\n ) : null}\n </span>\n <span className={css.headerActions}>\n <Button variant=\"outline\" size=\"sm\" disabled={refreshing || cacheAll.running} onClick={() => { void refresh() }}>\n {refreshing ? tt('templates.refreshing') : tt('templates.refresh')}\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={list === null || cacheAll.running}\n title={tt('templates.cacheAllHint')}\n onClick={() => { void cacheAllImages() }}\n >\n {cacheAll.running\n ? tt('templates.caching', { done: cacheAll.done, total: cacheAll.total })\n : cacheAll.total > 0 && cacheAll.done === cacheAll.total\n ? tt('templates.cached')\n : tt('templates.cacheAll')}\n </Button>\n <button type=\"button\" className={css.close} aria-label={tt('templates.close')} title={tt('templates.close')} onClick={onClose}>\n <svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" aria-hidden=\"true\"><path d=\"M4 4l8 8M12 4l-8 8\"/></svg>\n </button>\n </span>\n </header>\n\n <div className={css.toolbar}>\n <input\n ref={searchRef}\n type=\"search\"\n className={css.search}\n placeholder={tt('templates.search')}\n value={query}\n onChange={(event) => { setQuery(event.target.value) }}\n />\n <div className={css.categoryRow}>\n <button\n type=\"button\"\n className={css.categoryPill}\n data-active={category === '' ? '' : undefined}\n onClick={() => { setCategory('') }}\n >\n {tt('templates.all')}{list !== null ? ` ${list.total}` : ''}\n </button>\n {categories.map(entry => (\n <button\n key={entry.key}\n type=\"button\"\n className={css.categoryPill}\n data-active={category === entry.key ? '' : undefined}\n onClick={() => { setCategory(entry.key) }}\n >\n {entry.label} {entry.count}\n </button>\n ))}\n </div>\n </div>\n\n {notice !== null ? <div className={css.notice} role=\"status\">{notice}</div> : null}\n\n <div className={css.body}>\n {list === null && loadError === null ? (\n <div className={css.state} role=\"status\">\n <span className={css.spinner} />\n <span>{tt('templates.loading')}</span>\n </div>\n ) : null}\n\n {loadError !== null ? (\n <div className={css.state} role=\"alert\">\n <span>{tt('templates.loadFailed', { error: loadError })}</span>\n <Button variant=\"outline\" size=\"sm\" onClick={() => { setLoadError(null); setList(null); load() }}>\n {tt('templates.retry')}\n </Button>\n </div>\n ) : null}\n\n {list !== null && filtered.length === 0 ? (\n <div className={css.state}>{tt('templates.empty')}</div>\n ) : null}\n\n {list !== null && filtered.length > 0 ? (\n <div className={css.grid}>\n {filtered.map(item => (\n <button\n key={item.id}\n type=\"button\"\n className={css.card}\n onClick={() => { setSelected(item); setCopied(false) }}\n >\n <span className={css.thumbWrap}>\n <TemplateThumb item={item} />\n {item.featured ? <span className={css.featuredBadge}>{tt('templates.featured')}</span> : null}\n </span>\n <span className={css.cardBody}>\n <span className={css.cardTitle}>{item.title}</span>\n <span className={css.cardMeta}>\n <span className={css.cardCategory}>{item.categoryZh || item.category}</span>\n {item.sourceLabel !== '' ? <span className={css.cardSource}>{item.sourceLabel}</span> : null}\n </span>\n </span>\n </button>\n ))}\n </div>\n ) : null}\n </div>\n\n <footer className={css.footer}>\n <span className={css.attribution}>{tt('templates.attribution')}</span>\n <a className={css.sourceLink} href=\"https://vibeui.top/\" target=\"_blank\" rel=\"noreferrer\">\n {tt('templates.source')}\n </a>\n </footer>\n </section>\n\n {selected !== null ? (\n <div className={css.detailOverlay} onClick={() => { setSelected(null) }}>\n <section className={css.detail} onClick={(event) => { event.stopPropagation() }}>\n <div className={css.detailMedia}>\n {selected.image !== '' ? (\n <img className={css.detailImage} src={imageUrlOf(selected)} alt={selected.title} />\n ) : (\n <span className={css.thumbPlaceholder} aria-hidden=\"true\" />\n )}\n </div>\n <div className={css.detailInfo}>\n <h4 className={css.detailTitle}>{selected.title}</h4>\n <div className={css.detailMeta}>\n <span className={css.cardCategory}>{selected.categoryZh || selected.category}</span>\n {selected.sourceUrl !== '' ? (\n <a className={css.detailLink} href={selected.sourceUrl} target=\"_blank\" rel=\"noreferrer\">{selected.sourceLabel || selected.sourceUrl}</a>\n ) : null}\n {selected.githubUrl !== '' ? (\n <a className={css.detailLink} href={selected.githubUrl} target=\"_blank\" rel=\"noreferrer\">GitHub</a>\n ) : null}\n </div>\n <pre className={css.detailPrompt}>{selected.prompt}</pre>\n <div className={css.detailActions}>\n <Button variant=\"primary\" size=\"md\" onClick={() => { onUse(selected.prompt) }}>\n {tt('templates.use')}\n </Button>\n <Button variant=\"outline\" size=\"md\" onClick={() => { void copyPrompt(selected.prompt) }}>\n {copied ? tt('templates.copied') : tt('templates.copy')}\n </Button>\n <Button variant=\"outline\" size=\"md\" onClick={() => { setSelected(null) }}>\n {tt('templates.back')}\n </Button>\n </div>\n </div>\n </section>\n </div>\n ) : null}\n </div>,\n document.body,\n )\n}\n","/**\n * Image-model configuration shared by the host, panel, and Agent tools.\n * `/models` exposes candidates only: the configured list is the explicit\n * allow-list because OpenAI-compatible gateways rarely advertise modalities.\n */\n\nexport const DEFAULT_IMAGE_MODELS = ['gpt-image-2', 'grok-imagine-image'] as const\n\n/** Normalize user-entered model identifiers and retain a usable legacy default. */\nexport function normalizeImageModels(value: unknown): string[] {\n const candidates = Array.isArray(value) ? value : []\n const unique = new Set<string>()\n for (const candidate of candidates) {\n if (typeof candidate !== 'string') continue\n const model = candidate.trim()\n if (model !== '') unique.add(model)\n }\n return unique.size > 0 ? [...unique] : [...DEFAULT_IMAGE_MODELS]\n}\n","/**\n * The AI 生图 studio: a three-column layout — left, a card-grouped\n * configuration sidebar (mode tabs, prompt with counter, rounded parameter\n * selectors, model dropdown + generate button); center, the result canvas;\n * right, a persistent generation history column.\n *\n * Controls ride the system UI primitives (@deepseek-ai/dsh-client-ui-primitives,\n * a platform module) so the studio matches the dsh shell look by construction.\n */\n\nimport { useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport { Button, Pill } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { ImageGenApi } from './api.ts'\nimport { errorMessage, tt } from './helpers.ts'\nimport { TemplateLibrary } from './TemplateLibrary.tsx'\nimport type { GeneratedImage, GenerateMode, GenerateRequest, GenerationTask, HistoryEntry, HistoryImageRef, UpdateInfo } from '../protocol.ts'\nimport type { ImageGenConfig, ImageGenScope } from './settings-scope.ts'\nimport { DEFAULT_IMAGE_MODELS, normalizeImageModels } from '../image-models.ts'\nimport css from './panel.module.css'\n\n/** Size options, presented as aspect ratios (auto = let the model decide).\n * The host maps each ratio onto the model's own vocabulary: aspect_ratio for\n * Grok Imagine, the closest pixel size for OpenAI-compatible endpoints. */\nconst SIZES = ['auto', '1:1', '3:4', '4:3', '9:16', '2:3', '3:2', '16:9', '21:9'] as const\n\n/** Size option keys in the locale dictionary. */\nconst SIZE_KEYS: Record<string, 'size.auto' | 'size.square' | 'size.portrait34' | 'size.landscape43' | 'size.portrait916' | 'size.portrait23' | 'size.landscape32' | 'size.wide169' | 'size.ultrawide21'> = {\n auto: 'size.auto',\n '1:1': 'size.square',\n '3:4': 'size.portrait34',\n '4:3': 'size.landscape43',\n '9:16': 'size.portrait916',\n '2:3': 'size.portrait23',\n '3:2': 'size.landscape32',\n '16:9': 'size.wide169',\n '21:9': 'size.ultrawide21',\n}\n\n/** Quality options, shown as output-resolution tiers (auto = let the model\n * decide). The host maps them: resolution for Grok, quality level for\n * OpenAI-compatible endpoints (1k→low, 2k→medium, 4k→high). */\nconst QUALITIES = ['auto', '1k', '2k', '4k'] as const\n\n/** Detail options ('' = omit the passthrough). */\nconst DETAILS = ['', 'standard', 'high'] as const\n\nconst REF_IMAGE_MAX_BYTES = 10 * 1024 * 1024\nconst PREVIEW_SCALE_MIN = 0.5\nconst PREVIEW_SCALE_MAX = 3\nconst PREVIEW_SCALE_STEP = 0.25\n\n/** Legacy pixel sizes saved by older versions, mapped onto the current\n * aspect-ratio vocabulary so restoring old history entries still works. */\nconst LEGACY_SIZE_TO_RATIO: Record<string, string> = {\n '512x512': '1:1',\n '1024x1024': '1:1',\n '1536x1024': '3:2',\n '1024x1536': '2:3',\n '1792x1024': '16:9',\n '1024x1792': '9:16',\n}\n\n/** Legacy quality levels saved by older versions, mapped onto resolution. */\nconst LEGACY_QUALITY_TO_RES: Record<string, string> = {\n low: '1k',\n medium: '2k',\n high: '4k',\n}\n\n/** Normalize a saved size value into a current dropdown option. */\nfunction normalizeSize(value: string): string {\n if ((SIZES as readonly string[]).includes(value)) return value\n return LEGACY_SIZE_TO_RATIO[value] ?? 'auto'\n}\n\n/** Normalize a saved quality value into a current dropdown option. */\nfunction normalizeQuality(value: string): string {\n if ((QUALITIES as readonly string[]).includes(value)) return value\n return LEGACY_QUALITY_TO_RES[value] ?? 'auto'\n}\n\nfunction clampPreviewScale(scale: number): number {\n return Math.min(PREVIEW_SCALE_MAX, Math.max(PREVIEW_SCALE_MIN, scale))\n}\n\n/** Read the current config from the settings scope snapshot. */\nfunction useConfig(scope: ImageGenScope): ImageGenConfig | undefined {\n const [value, setValue] = useState(scope.getSnapshot().value)\n useEffect(() => scope.subscribe(() => { setValue(scope.getSnapshot().value) }), [scope])\n return value\n}\n\n/** Track one redacted secret field without exposing its value to the panel. */\nfunction useSecretSet(scope: ImageGenScope, field: string): boolean {\n const [isSet, setIsSet] = useState(scope.getSecretSetSnapshot(field))\n useEffect(() => scope.subscribeSecretSets(() => { setIsSet(scope.getSecretSetSnapshot(field)) }), [field, scope])\n return isSet\n}\n\n/** Tick a seconds counter while `running`. */\nfunction useElapsed(running: boolean, startedAt: number | null): number {\n const [elapsed, setElapsed] = useState(0)\n useEffect(() => {\n if (!running || startedAt === null) return\n const timer = window.setInterval(() => {\n setElapsed(Math.max(1, Math.round((Date.now() - startedAt) / 1000)))\n }, 1000)\n return () => window.clearInterval(timer)\n }, [running, startedAt])\n return elapsed\n}\n\n/** Data URL for a generated image. */\nfunction srcOf(image: GeneratedImage): string {\n return `data:${image.mime};base64,${image.b64}`\n}\n\n/** Fetch persisted history image refs and decode them back to in-memory\n * GeneratedImage[] (base64), so the canvas/preview can reuse the same\n * rendering path as a fresh generation. */\nasync function historyImagesToGenerated(refs: HistoryImageRef[]): Promise<GeneratedImage[]> {\n return Promise.all(refs.map(async ref => {\n const response = await fetch(ref.url)\n if (!response.ok) throw new Error(`HTTP ${response.status}`)\n const blob = await response.blob()\n const dataUrl = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => resolve(typeof reader.result === 'string' ? reader.result : '')\n reader.onerror = () => reject(new Error('image read failed'))\n reader.readAsDataURL(blob)\n })\n const comma = dataUrl.indexOf(',')\n return {\n b64: comma >= 0 ? dataUrl.slice(comma + 1) : '',\n mime: ref.mime,\n ...ref.revisedPrompt === undefined ? {} : { revisedPrompt: ref.revisedPrompt },\n }\n }))\n}\n\n/** Compact, locale-independent timestamp for history entries. */\nfunction formatTime(timestamp: number): string {\n const d = new Date(timestamp)\n const pad = (n: number): string => String(n).padStart(2, '0')\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`\n}\n\n/** Studio tabs: the two generation modes plus the gallery view. */\ntype PanelTab = GenerateMode | 'gallery'\n\ntype GalleryFilter = string\ntype ComparisonSession = { taskIds: string[]; prompt: string }\n\n/** Render the studio. */\nexport function ImageGenPanel(props: {\n api: ImageGenApi\n scope: ImageGenScope\n}) {\n const { api, scope } = props\n const config = useConfig(scope)\n const enabled = config?.enabled ?? true\n const apiUrl = config?.apiUrl ?? ''\n const configured = apiUrl.trim() !== ''\n const apiKeySet = useSecretSet(scope, 'apiKey')\n const promptKeySet = useSecretSet(scope, 'promptApiKey')\n const connected = enabled && configured && apiKeySet\n const imageModels = normalizeImageModels(config?.imageModels)\n\n const [tab, setTab] = useState<PanelTab>('text')\n const [prompt, setPrompt] = useState('')\n const [size, setSize] = useState<string>('auto')\n const [quality, setQuality] = useState<string>('auto')\n const [count, setCount] = useState(1)\n const [detail, setDetail] = useState('')\n const [model, setModel] = useState<string>(DEFAULT_IMAGE_MODELS[0])\n const [compareEnabled, setCompareEnabled] = useState(false)\n const [compareModels, setCompareModels] = useState<string[]>([...DEFAULT_IMAGE_MODELS])\n const [modelOpen, setModelOpen] = useState(false)\n const [refImage, setRefImage] = useState<{ dataUrl: string; name: string } | null>(null)\n const [images, setImages] = useState<GeneratedImage[]>([])\n const [error, setError] = useState<string | null>(null)\n const [generating, setGenerating] = useState(false)\n const [enhancing, setEnhancing] = useState(false)\n const [configGuide, setConfigGuide] = useState<'generation' | 'enhancement' | 'disabled' | null>(null)\n const [startedAt, setStartedAt] = useState<number | null>(null)\n const [history, setHistory] = useState<HistoryEntry[]>([])\n const [viewingHistoryId, setViewingHistoryId] = useState<string | null>(null)\n const [gallery, setGallery] = useState<HistoryEntry[]>([])\n const [galleryViewingId, setGalleryViewingId] = useState<string | null>(null)\n const [galleryAdding, setGalleryAdding] = useState(false)\n const [galleryMessage, setGalleryMessage] = useState<string | null>(null)\n const [galleryFilter, setGalleryFilter] = useState<GalleryFilter>('all')\n const [galleryRatio, setGalleryRatio] = useState('all')\n const [galleryTagFilter, setGalleryTagFilter] = useState<string | null>(null)\n const [galleryView, setGalleryView] = useState<'masonry' | 'grid'>('masonry')\n const [gallerySort, setGallerySort] = useState<'newest' | 'oldest'>('newest')\n const [galleryQuery, setGalleryQuery] = useState('')\n const [galleryTagInput, setGalleryTagInput] = useState('')\n const [editingGalleryTagsId, setEditingGalleryTagsId] = useState<string | null>(null)\n const [galleryTagEditInput, setGalleryTagEditInput] = useState('')\n const [selectedGalleryIds, setSelectedGalleryIds] = useState<Set<string>>(new Set())\n const [gallerySelecting, setGallerySelecting] = useState(false)\n const [historyQuery, setHistoryQuery] = useState('')\n const [historyModelFilter, setHistoryModelFilter] = useState('all')\n const [historyRatioFilter, setHistoryRatioFilter] = useState('all')\n const [preview, setPreview] = useState<{ images: GeneratedImage[]; index: number } | null>(null)\n const [previewScale, setPreviewScale] = useState(1)\n const [promptCopied, setPromptCopied] = useState(false)\n const [update, setUpdate] = useState<UpdateInfo | null>(null)\n const [updating, setUpdating] = useState(false)\n const [updateMessage, setUpdateMessage] = useState<string | null>(null)\n const [updateResult, setUpdateResult] = useState<'success' | 'failed' | null>(null)\n const [libraryOpen, setLibraryOpen] = useState(false)\n const [tasks, setTasks] = useState<GenerationTask[]>([])\n const [taskTrayOpen, setTaskTrayOpen] = useState(false)\n const [comparison, setComparison] = useState<ComparisonSession | null>(null)\n const [comparisonFullscreen, setComparisonFullscreen] = useState(false)\n const fileInput = useRef<HTMLInputElement>(null)\n const previewStage = useRef<HTMLDivElement>(null)\n const elapsed = useElapsed(generating, startedAt)\n\n // A saved settings change is authoritative. Keep the active selection and\n // comparison choices in that allow-list without disturbing valid choices.\n const imageModelKey = imageModels.join('\\u0000')\n useEffect(() => {\n setModel(previous => imageModels.includes(previous) ? previous : imageModels[0])\n setCompareModels(previous => {\n const retained = previous.filter(candidate => imageModels.includes(candidate))\n return retained.length > 0 ? retained : [imageModels[0]]\n })\n }, [imageModelKey])\n\n const filteredGallery = gallery\n .filter(entry => {\n if (galleryFilter === 'all') return true\n if (galleryFilter === 'text' || galleryFilter === 'edit') return entry.mode === galleryFilter\n return entry.model === galleryFilter\n })\n .filter(entry => galleryRatio === 'all' || normalizeSize(entry.size) === galleryRatio)\n .filter(entry => galleryTagFilter === null || (entry.tags ?? []).includes(galleryTagFilter))\n .filter(entry => galleryQuery.trim() === '' || `${entry.prompt} ${entry.model} ${(entry.tags ?? []).join(' ')}`.toLocaleLowerCase().includes(galleryQuery.trim().toLocaleLowerCase()))\n .slice()\n .sort((a, b) => gallerySort === 'newest' ? b.createdAt - a.createdAt : a.createdAt - b.createdAt)\n\n const galleryTagOptions = [...new Set(gallery.flatMap(entry => entry.tags ?? []))].sort((a, b) => a.localeCompare(b))\n const galleryModels = [...new Set([...imageModels, ...gallery.map(entry => entry.model)])]\n\n const filteredHistory = history.filter(entry => {\n const query = historyQuery.trim().toLocaleLowerCase()\n return (query === '' || `${entry.prompt} ${entry.model}`.toLocaleLowerCase().includes(query))\n && (historyModelFilter === 'all' || entry.model === historyModelFilter)\n && (historyRatioFilter === 'all' || normalizeSize(entry.size) === historyRatioFilter)\n })\n\n // Load the host-persisted history and gallery once on mount (they live in\n // ~/.dsh on the DSH host, so every browser/device sees the same lists).\n useEffect(() => {\n let disposed = false\n api.historyList()\n .then(entries => { if (!disposed) setHistory(entries) })\n .catch(() => { /* history unavailable — leave the list empty */ })\n api.galleryList()\n .then(entries => { if (!disposed) setGallery(entries) })\n .catch(() => { /* gallery unavailable — leave the list empty */ })\n return () => { disposed = true }\n }, [api])\n\n useEffect(() => {\n let disposed = false\n const refresh = (): void => {\n void api.taskList().then(next => {\n if (disposed) return\n setTasks(previous => {\n const completed = next.find(task => task.status === 'completed'\n && !previous.some(old => old.id === task.id && old.status === 'completed')\n && !comparison?.taskIds.includes(task.id))\n if (completed?.result !== undefined) {\n setImages(completed.result.images)\n if (completed.result.history !== undefined) setHistory(completed.result.history)\n setError(completed.result.historyError ?? null)\n }\n return next\n })\n }).catch(() => {})\n }\n refresh()\n const timer = window.setInterval(refresh, 1500)\n return () => { disposed = true; window.clearInterval(timer) }\n }, [api, comparison])\n\n // Close the model dropdown when clicking anywhere outside it.\n const modelMenuRef = useRef<HTMLDivElement>(null)\n useEffect(() => {\n if (!modelOpen) return\n const onPointer = (event: MouseEvent | FocusEvent): void => {\n const target = event.target\n if (target instanceof Node && modelMenuRef.current?.contains(target)) return\n setModelOpen(false)\n }\n document.addEventListener('mousedown', onPointer)\n document.addEventListener('focusin', onPointer)\n return () => {\n document.removeEventListener('mousedown', onPointer)\n document.removeEventListener('focusin', onPointer)\n }\n }, [modelOpen])\n\n // Release checks are host-mediated and intentionally best-effort: a GitHub\n // outage must never make the image-generation studio unavailable.\n useEffect(() => {\n let disposed = false\n api.updateCheck()\n .then(info => {\n if (!disposed && info.updateAvailable) setUpdate(info)\n })\n .catch(() => { /* update discovery is optional */ })\n return () => { disposed = true }\n }, [api])\n\n const applyUpdate = async (): Promise<void> => {\n if (update === null || updating) return\n setUpdating(true)\n setUpdateMessage(null)\n setUpdateResult(null)\n try {\n const result = await api.updateApply(update.latestVersion)\n setUpdateMessage(tt('update.success', { version: result.updatedVersion }))\n setUpdateResult('success')\n } catch {\n setUpdateMessage(tt('update.failed'))\n setUpdateResult('failed')\n } finally {\n setUpdating(false)\n }\n }\n\n const openSettingsGuide = (kind: 'generation' | 'enhancement' | 'disabled'): void => {\n setConfigGuide(kind)\n const openPluginSettings = (): void => {\n const pluginButton = Array.from(document.querySelectorAll<HTMLButtonElement>('button')).find(button => /^(插件|Plugins)$/.test(button.textContent?.trim() ?? ''))\n pluginButton?.click()\n window.setTimeout(() => {\n const imageGenButton = Array.from(document.querySelectorAll<HTMLButtonElement>('button')).find(button => /dsh-imagegen/i.test(button.textContent ?? ''))\n if (imageGenButton?.getAttribute('aria-expanded') !== 'true') imageGenButton?.click()\n }, 0)\n }\n const settingsButton = Array.from(document.querySelectorAll<HTMLButtonElement>('button')).find(button => /^(设置|Settings)$/.test(button.textContent?.trim() ?? ''))\n if (settingsButton?.getAttribute('aria-expanded') !== 'true') settingsButton?.click()\n window.setTimeout(openPluginSettings, 0)\n }\n\n const enhanceCurrentPrompt = async (): Promise<void> => {\n if (prompt.trim() === '' || enhancing) return\n const promptEndpointConfigured = (config?.promptApiUrl ?? '').trim() !== '' || configured\n if ((config?.promptModel ?? '').trim() === '' || !promptEndpointConfigured || (!promptKeySet && !apiKeySet)) {\n openSettingsGuide('enhancement')\n return\n }\n setEnhancing(true)\n setError(null)\n try {\n setPrompt(await api.enhancePrompt(prompt))\n } catch (caught) {\n setError(errorMessage(caught))\n } finally {\n setEnhancing(false)\n }\n }\n\n /** Read an uploaded reference image into a data URL. */\n const acceptFile = (file: File | undefined): void => {\n if (file === undefined) return\n if (!file.type.startsWith('image/')) {\n setError(tt('edit.uploadHint'))\n return\n }\n if (file.size > REF_IMAGE_MAX_BYTES) {\n setError(tt('edit.uploadHint'))\n return\n }\n const reader = new FileReader()\n reader.onload = () => {\n if (typeof reader.result === 'string') setRefImage({ dataUrl: reader.result, name: file.name })\n }\n reader.onerror = () => { setError(tt('edit.uploadHint')) }\n reader.readAsDataURL(file)\n }\n\n /** Run one generation. */\n const handleGenerate = async (): Promise<void> => {\n if (generating) return\n if (!enabled) {\n openSettingsGuide('disabled')\n return\n }\n if (!configured || !apiKeySet) {\n openSettingsGuide('generation')\n return\n }\n const promptText = prompt.trim()\n if (promptText === '') {\n setError(tt('prompt.required'))\n return\n }\n if (tab === 'edit' && refImage === null) {\n setError(tt('edit.required'))\n return\n }\n const request: GenerateRequest = {\n mode: tab === 'gallery' ? 'text' : tab,\n model: imageModels.includes(model) ? model : imageModels[0],\n prompt: promptText,\n size,\n quality,\n n: count,\n detail,\n ...tab === 'edit' && refImage !== null ? { image: refImage.dataUrl } : {},\n ...tab === 'edit' && refImage !== null ? { refName: refImage.name } : {},\n }\n setError(null)\n try {\n const targetModels = (compareEnabled ? compareModels : [request.model]).filter(candidate => imageModels.includes(candidate))\n if (targetModels.length === 0) {\n setError(tt('compare.selectRequired'))\n return\n }\n const submitted = await Promise.all(targetModels.map(targetModel => api.taskSubmit({ ...request, model: targetModel })))\n setTasks(previous => [...submitted, ...previous.filter(item => !submitted.some(task => task.id === item.id))])\n setComparison(targetModels.length > 1 ? { taskIds: submitted.map(task => task.id), prompt: promptText } : null)\n } catch (caught) {\n setError(errorMessage(caught))\n }\n }\n\n /** Open the full-screen image preview at a given index. */\n const openPreview = (previewImages: GeneratedImage[], index: number): void => {\n setPreview({ images: previewImages, index })\n setPreviewScale(1)\n setPromptCopied(false)\n }\n\n const closePreview = (): void => {\n setPreview(null)\n setPreviewScale(1)\n setPromptCopied(false)\n }\n\n /** Step the preview by ±1, wrapping around. */\n const stepPreview = (delta: number): void => {\n setPreviewScale(1)\n setPromptCopied(false)\n setPreview(current => {\n if (current === null) return null\n const total = current.images.length\n return { images: current.images, index: (current.index + delta + total) % total }\n })\n }\n\n // Keyboard navigation for the preview overlay.\n useEffect(() => {\n if (preview === null) return\n const onKey = (event: KeyboardEvent): void => {\n if (event.key === 'Escape') closePreview()\n else if (event.key === 'ArrowLeft') stepPreview(-1)\n else if (event.key === 'ArrowRight') stepPreview(1)\n else if (event.key === '+' || event.key === '=') setPreviewScale(current => clampPreviewScale(current + PREVIEW_SCALE_STEP))\n else if (event.key === '-') setPreviewScale(current => clampPreviewScale(current - PREVIEW_SCALE_STEP))\n else if (event.key === '0') setPreviewScale(1)\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [preview])\n\n // A scaled image owns real scrollable space, rather than being visually\n // transformed and clipped. Recenter the viewport after every zoom or slide.\n useEffect(() => {\n if (preview === null) return\n const frame = window.requestAnimationFrame(() => {\n const stage = previewStage.current\n if (stage === null) return\n stage.scrollLeft = Math.max(0, (stage.scrollWidth - stage.clientWidth) / 2)\n stage.scrollTop = Math.max(0, (stage.scrollHeight - stage.clientHeight) / 2)\n })\n return () => window.cancelAnimationFrame(frame)\n }, [preview, previewScale])\n\n /** Load a past generation's images into the canvas. */\n const viewHistoryEntry = async (entry: HistoryEntry): Promise<void> => {\n try {\n setImages(await historyImagesToGenerated(entry.images))\n setError(null)\n setViewingHistoryId(entry.id)\n setGalleryViewingId(null)\n } catch (caught) {\n setError(errorMessage(caught))\n }\n }\n\n /** Restore a past generation's parameters (and its images) into the form. */\n const restoreHistoryEntry = async (entry: HistoryEntry): Promise<void> => {\n try {\n const restored = await historyImagesToGenerated(entry.images)\n setTab(entry.mode)\n setPrompt(entry.prompt)\n setSize(normalizeSize(entry.size))\n setQuality(normalizeQuality(entry.quality))\n setDetail((DETAILS as readonly string[]).includes(entry.detail) ? entry.detail : '')\n setCount(entry.n >= 1 && entry.n <= 4 ? entry.n : 1)\n setModel(imageModels.includes(entry.model) ? entry.model : imageModels[0])\n setRefImage(null)\n setImages(restored)\n setError(null)\n setViewingHistoryId(entry.id)\n setGalleryViewingId(null)\n } catch (caught) {\n setError(errorMessage(caught))\n }\n }\n\n /** Remove one history entry. */\n const deleteHistoryEntry = async (id: string): Promise<void> => {\n setHistory(history.filter(entry => entry.id !== id))\n if (viewingHistoryId === id) setViewingHistoryId(null)\n try {\n setHistory(await api.historyRemove(id))\n } catch {\n // Keep the optimistic local removal.\n }\n }\n\n /** Remove all history entries. */\n const clearHistory = async (): Promise<void> => {\n setHistory([])\n setViewingHistoryId(null)\n try {\n setHistory(await api.historyClear())\n } catch {\n // Keep the cleared local state.\n }\n }\n\n /** Add one generated image to the gallery (host deduplicates by content).\n * `entry` makes the action available from a history/gallery list item (its\n * metadata + first image are saved); otherwise the current form state is\n * used. */\n const addToGallery = async (image: GeneratedImage, entry?: HistoryEntry): Promise<void> => {\n if (galleryAdding || tab === 'gallery') return\n const source = entry ?? viewingEntry ?? {\n mode: tab === 'edit' ? 'edit' as GenerateMode : 'text' as GenerateMode,\n model,\n prompt: prompt.trim(),\n size,\n quality,\n detail,\n ...refImage !== null ? { refName: refImage.name } : {},\n }\n setGalleryAdding(true)\n try {\n const result = await api.galleryAppend({\n id: '', // the host assigns a fresh id\n createdAt: Date.now(),\n mode: source.mode,\n model: source.model,\n prompt: source.prompt,\n size: source.size,\n quality: source.quality,\n detail: source.detail,\n n: 1,\n images: [image],\n ...source.refName === undefined ? {} : { refName: source.refName },\n })\n setGallery(result.entries)\n setGalleryMessage(result.added ? tt('gallery.added') : tt('gallery.already'))\n window.setTimeout(() => { setGalleryMessage(null) }, 2200)\n } catch (caught) {\n setError(errorMessage(caught))\n } finally {\n setGalleryAdding(false)\n }\n }\n\n /** Add one history entry's first image to the gallery (fetches it from the\n * history image route, then delegates to addToGallery). */\n const addHistoryEntryToGallery = async (entry: HistoryEntry): Promise<void> => {\n if (galleryAdding || entry.images.length === 0) return\n try {\n const [image] = await historyImagesToGenerated(entry.images.slice(0, 1))\n if (image === undefined) return\n await addToGallery(image, entry)\n } catch (caught) {\n setError(errorMessage(caught))\n }\n }\n\n /** View a gallery image in the canvas. */\n const viewGalleryEntry = async (entry: HistoryEntry): Promise<void> => {\n try {\n const restored = await historyImagesToGenerated(entry.images)\n setImages(restored)\n setError(null)\n setViewingHistoryId(null)\n setGalleryViewingId(entry.id)\n if (restored.length > 0) openPreview(restored, 0)\n } catch (caught) {\n setError(errorMessage(caught))\n }\n }\n\n /** Restore a gallery entry's parameters (and its images) into the form. */\n const restoreGalleryEntry = async (entry: HistoryEntry): Promise<void> => {\n try {\n const restored = await historyImagesToGenerated(entry.images)\n setTab(entry.mode)\n setPrompt(entry.prompt)\n setSize(normalizeSize(entry.size))\n setQuality(normalizeQuality(entry.quality))\n setDetail((DETAILS as readonly string[]).includes(entry.detail) ? entry.detail : '')\n setCount(entry.n >= 1 && entry.n <= 4 ? entry.n : 1)\n setModel(imageModels.includes(entry.model) ? entry.model : imageModels[0])\n setRefImage(null)\n setImages(restored)\n setError(null)\n setViewingHistoryId(null)\n setGalleryViewingId(null)\n } catch (caught) {\n setError(errorMessage(caught))\n }\n }\n\n /** Remove one gallery entry. */\n const deleteGalleryEntry = async (id: string): Promise<void> => {\n setGallery(gallery.filter(entry => entry.id !== id))\n if (galleryViewingId === id) setGalleryViewingId(null)\n try {\n setGallery(await api.galleryRemove(id))\n } catch {\n // Keep the optimistic local removal.\n }\n }\n\n /** Remove every gallery entry. */\n const clearGalleryAll = async (): Promise<void> => {\n setGallery([])\n setGalleryViewingId(null)\n try {\n setGallery(await api.galleryClear())\n } catch {\n // Keep the cleared local state.\n }\n }\n\n const applyGalleryTags = async (): Promise<void> => {\n const tags = galleryTagInput.split(',').map(tag => tag.trim()).filter(Boolean)\n if (tags.length === 0 || selectedGalleryIds.size === 0) return\n try {\n let next = gallery\n for (const id of selectedGalleryIds) {\n const existing = next.find(entry => entry.id === id)?.tags ?? []\n next = await api.gallerySetTags(id, [...existing, ...tags])\n }\n setGallery(next)\n setGalleryTagInput('')\n } catch (caught) { setError(errorMessage(caught)) }\n }\n\n const startEditingGalleryTags = (entry: HistoryEntry): void => {\n setEditingGalleryTagsId(entry.id)\n setGalleryTagEditInput((entry.tags ?? []).join(', '))\n }\n\n const saveGalleryTags = async (id: string): Promise<void> => {\n const tags = galleryTagEditInput.split(',').map(tag => tag.trim()).filter(Boolean)\n try {\n setGallery(await api.gallerySetTags(id, tags))\n setEditingGalleryTagsId(null)\n setGalleryTagEditInput('')\n } catch (caught) { setError(errorMessage(caught)) }\n }\n\n const toggleGallerySelection = (id: string): void => {\n setSelectedGalleryIds(previous => {\n const next = new Set(previous)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n return next\n })\n }\n\n const clearGallerySelection = (): void => {\n setSelectedGalleryIds(new Set())\n setGallerySelecting(false)\n }\n\n const exportGalleryJson = (): void => {\n const entries = gallery.filter(entry => selectedGalleryIds.has(entry.id))\n const blob = new Blob([JSON.stringify(entries, null, 2)], { type: 'application/json' })\n const url = URL.createObjectURL(blob)\n const anchor = document.createElement('a')\n anchor.href = url\n anchor.download = `dsh-imagegen-gallery-${new Date().toISOString().slice(0, 10)}.json`\n anchor.click()\n URL.revokeObjectURL(url)\n }\n\n const downloadGalleryImages = (): void => {\n gallery.filter(entry => selectedGalleryIds.has(entry.id)).forEach((entry, index) => {\n const image = entry.images[0]\n if (image === undefined) return\n const anchor = document.createElement('a')\n anchor.href = image.url\n anchor.download = `dsh-gallery-${index + 1}.${extensionOf(image.mime)}`\n anchor.click()\n })\n }\n\n const generateDisabled = generating\n const viewingEntry = viewingHistoryId === null ? null : history.find(entry => entry.id === viewingHistoryId) ?? null\n const viewingGalleryEntry = galleryViewingId === null ? null : gallery.find(entry => entry.id === galleryViewingId) ?? null\n const previewImage = preview === null ? null : preview.images[preview.index] ?? null\n const comparisonTasks = comparison === null ? [] : comparison.taskIds.map(id => tasks.find(task => task.id === id)).filter((task): task is GenerationTask => task !== undefined)\n const comparisonResults = comparisonTasks.filter(task => task.status === 'completed' && task.result !== undefined)\n const previewFrameScale = Math.max(1, previewScale)\n const previewImageScale = previewScale / previewFrameScale\n\n const copyPreviewPrompt = async (text: string): Promise<void> => {\n try {\n if (navigator.clipboard?.writeText !== undefined) {\n await navigator.clipboard.writeText(text)\n } else {\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 const copied = document.execCommand('copy')\n textarea.remove()\n if (!copied) throw new Error('copy failed')\n }\n setPromptCopied(true)\n window.setTimeout(() => { setPromptCopied(false) }, 1800)\n } catch {\n setPromptCopied(false)\n }\n }\n\n const addPreviewToEdit = (): void => {\n if (previewImage === null || preview === null) return\n setTab('edit')\n setRefImage({\n dataUrl: srcOf(previewImage),\n name: `dsh-image-${preview.index + 1}.${extensionOf(previewImage.mime)}`,\n })\n if (prompt.trim() === '' && previewImage.revisedPrompt !== undefined) setPrompt(previewImage.revisedPrompt)\n setError(null)\n closePreview()\n }\n\n return (\n <div className={css.panel}>\n <header className={css.panelHeader}>\n <span className={css.panelHeading}>\n <h2 className={css.panelTitle}>{tt('panel.title')}</h2>\n <a\n className={css.githubLink}\n href=\"https://github.com/dickpy/dsh-imagegen\"\n target=\"_blank\"\n rel=\"noreferrer\"\n title={tt('panel.githubTip')}\n aria-label={tt('panel.githubTip')}\n >\n <svg viewBox=\"0 0 16 16\" width=\"15\" height=\"15\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8z\"/></svg>\n </a>\n </span>\n <button\n type=\"button\"\n className={css.connectionStatus}\n data-connected={connected ? 'true' : 'false'}\n aria-label={tt(connected ? 'connection.connected' : 'connection.disconnected')}\n >\n <span className={css.connectionDot} aria-hidden=\"true\" />\n {tt(connected ? 'connection.connected' : 'connection.disconnected')}\n </button>\n </header>\n\n {update !== null ? (\n <div className={css.updateBanner} data-kind={updateResult === 'success' ? 'ok' : 'warn'}>\n <span className={css.updateText}>\n {updateMessage ?? tt('update.available', { version: update.latestVersion })}\n </span>\n <span className={css.updateActions}>\n <a className={css.updateRelease} href={update.releaseUrl} target=\"_blank\" rel=\"noreferrer\">{tt('update.release')}</a>\n <Button variant=\"primary\" size=\"sm\" disabled={updating || updateMessage !== null} onClick={() => { void applyUpdate() }}>\n {updating ? tt('update.installing') : tt('update.install')}\n </Button>\n </span>\n </div>\n ) : null}\n\n <div className={css.studio}>\n {/* ---------------------------------------------------- config sidebar */}\n <aside className={css.config} data-gallery={tab === 'gallery' ? 'true' : undefined}>\n {tab === 'gallery' ? (\n <div className={css.galleryFilters}>\n <div className={css.galleryFilterHeading}>{tt('gallery.categories')}</div>\n {[\n ['all', tt('gallery.all')],\n ['text', tt('mode.text')],\n ['edit', tt('mode.edit')],\n ...galleryModels.map(value => [value, value]),\n ].map(([value, label]) => (\n <button\n key={value}\n type=\"button\"\n className={css.galleryFilter}\n data-active={galleryFilter === value ? '' : undefined}\n onClick={() => { setGalleryFilter(value) }}\n >\n <span>{label}</span>\n <span className={css.galleryFilterCount}>{gallery.filter(entry => value === 'all' || value === 'text' || value === 'edit' ? (value === 'all' ? true : entry.mode === value) : entry.model === value).length}</span>\n </button>\n ))}\n <div className={css.galleryFilterDivider} />\n <div className={css.galleryFilterHeading}>{tt('gallery.ratio')}</div>\n <div className={css.galleryRatioList}>\n {(['all', '1:1', '3:4', '4:3', '16:9'] as const).map(ratio => (\n <button key={ratio} type=\"button\" className={css.galleryRatio} data-active={galleryRatio === ratio ? '' : undefined} onClick={() => { setGalleryRatio(ratio) }}>\n {ratio === 'all' ? tt('gallery.all') : ratio}\n </button>\n ))}\n </div>\n {galleryTagOptions.length > 0 ? (\n <>\n <div className={css.galleryFilterDivider} />\n <div className={css.galleryFilterHeading}>{tt('gallery.tags')}</div>\n <div className={css.galleryTagFilterList}>\n {galleryTagOptions.map(tag => (\n <button key={tag} type=\"button\" className={css.galleryTagFilter} data-active={galleryTagFilter === tag ? '' : undefined} onClick={() => { setGalleryTagFilter(previous => previous === tag ? null : tag) }}>\n <span>{tag}</span>\n <span>{gallery.filter(entry => (entry.tags ?? []).includes(tag)).length}</span>\n </button>\n ))}\n </div>\n </>\n ) : null}\n <div className={css.galleryFilterNote}>{tt('gallery.filterHint')}</div>\n </div>\n ) : null}\n <div className={css.configScroll}>\n {/* mode / gallery tabs */}\n <section className={css.card}>\n <div className={css.modeRow} role=\"tablist\" aria-label={tt('panel.title')}>\n <Pill active={tab === 'text'} onClick={() => { setTab('text') }} className={css.modePill}>{tt('mode.text')}</Pill>\n <Pill active={tab === 'edit'} onClick={() => { setTab('edit') }} className={css.modePill}>{tt('mode.edit')}</Pill>\n <Pill active={tab === 'gallery'} onClick={() => { setTab('gallery') }} className={css.modePill}>{tt('gallery.title')}</Pill>\n </div>\n </section>\n\n {/* reference image (edit mode) */}\n {tab === 'edit' ? (\n <section className={css.card}>\n {refImage === null\n ? (\n <button\n type=\"button\"\n className={css.uploadBox}\n onClick={() => { fileInput.current?.click() }}\n onDragOver={(event) => { event.preventDefault() }}\n onDrop={(event) => {\n event.preventDefault()\n acceptFile(event.dataTransfer.files?.[0])\n }}\n >\n <span className={css.uploadIcon}>\n <svg viewBox=\"0 0 16 16\" width=\"18\" height=\"18\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.3\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><path d=\"M8 10.5V3\"/><path d=\"M5 5.5l3-3 3 3\"/><path d=\"M2.5 9v3.5h11V9\"/></svg>\n </span>\n <span>{tt('edit.upload')}</span>\n <span className={css.uploadHint}>{tt('edit.uploadHint')}</span>\n </button>\n )\n : (\n <div className={css.reference}>\n <img className={css.referenceImage} src={refImage.dataUrl} alt={refImage.name} />\n <div className={css.referenceActions}>\n <Button variant=\"outline\" size=\"sm\" onClick={() => { fileInput.current?.click() }}>\n {tt('edit.change')}\n </Button>\n <Button variant=\"outline\" size=\"sm\" onClick={() => { setRefImage(null) }}>\n {tt('edit.remove')}\n </Button>\n </div>\n </div>\n )}\n <input\n ref={fileInput}\n type=\"file\"\n accept=\"image/png,image/jpeg,image/webp,image/gif\"\n className={css.hiddenFile}\n onChange={(event) => {\n acceptFile(event.target.files?.[0])\n event.target.value = ''\n }}\n />\n </section>\n ) : null}\n\n {/* prompt */}\n <section className={css.card}>\n <textarea\n className={css.prompt}\n value={prompt}\n placeholder={tt('prompt.placeholder')}\n onChange={(event) => { setPrompt(event.target.value) }}\n />\n <div className={css.promptFooter}>\n <button\n type=\"button\"\n className={css.templatesButton}\n title={tt('templates.title')}\n onClick={() => { setLibraryOpen(true) }}\n >\n <svg viewBox=\"0 0 16 16\" width=\"12\" height=\"12\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.4\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><path d=\"M2.5 3.5h11M2.5 8h11M2.5 12.5h7\"/></svg>\n {tt('templates.open')}\n </button>\n <button\n type=\"button\"\n className={css.enhanceButton}\n disabled={prompt.trim() === '' || enhancing}\n title={tt('prompt.enhanceHint')}\n onClick={() => { void enhanceCurrentPrompt() }}\n >\n {enhancing ? tt('prompt.enhancing') : tt('prompt.enhance')}\n </button>\n <span className={css.promptCount}>{tt('prompt.count', { count: prompt.length })}</span>\n </div>\n </section>\n\n {/* parameters */}\n <section className={css.card}>\n <div className={css.paramGroup}>\n <span className={css.paramLabel}>{tt('params.size')}</span>\n <div className={css.optionGrid}>\n {SIZES.map(option => (\n <Pill\n key={option}\n active={size === option}\n onClick={() => { setSize(option) }}\n className={css.optionPill}\n >\n {tt(SIZE_KEYS[option] ?? 'size.auto')}\n </Pill>\n ))}\n </div>\n </div>\n <div className={css.paramGroup}>\n <span className={css.paramLabel}>{tt('params.quality')}</span>\n <div className={css.optionRow}>\n {QUALITIES.map(option => (\n <Pill\n key={option}\n active={quality === option}\n onClick={() => { setQuality(option) }}\n className={css.optionPill}\n >\n {tt(`quality.${option}` as const)}\n </Pill>\n ))}\n </div>\n </div>\n <div className={css.paramGroup}>\n <span className={css.paramLabel}>{tt('params.count')}</span>\n <div className={css.optionRow}>\n {[1, 2, 3, 4].map(option => (\n <Pill\n key={option}\n active={count === option}\n onClick={() => { setCount(option) }}\n className={css.optionPill}\n >\n {tt(`count.${option === 1 ? 'one' : option === 2 ? 'two' : option === 3 ? 'three' : 'four'}` as const)}\n </Pill>\n ))}\n </div>\n </div>\n <div className={css.paramGroup}>\n <span className={css.paramLabel}>{tt('params.detail')}</span>\n <div className={css.optionRow}>\n {DETAILS.map(option => (\n <Pill\n key={option === '' ? 'auto' : option}\n active={detail === option}\n onClick={() => { setDetail(option) }}\n className={css.optionPill}\n >\n {tt(option === '' ? 'detail.auto' : option === 'standard' ? 'detail.standard' : 'detail.high')}\n </Pill>\n ))}\n </div>\n <span className={css.paramHint}>{tt('detail.hint')}</span>\n </div>\n </section>\n </div>\n\n {/* footer: model + generate — a fixed sibling of the scroll area, so\n it never overlaps the cards scrolling above it. */}\n <section className={css.footer}>\n <label className={css.modelWrap}>\n <span className={css.modelLabel}>{tt('model.label')}</span>\n <span ref={modelMenuRef} className={css.modelMenu} data-open={modelOpen ? 'true' : 'false'}>\n <button\n type=\"button\"\n className={css.modelSelect}\n disabled={generating}\n aria-haspopup=\"listbox\"\n aria-expanded={modelOpen}\n onClick={() => { setModelOpen(open => !open) }}\n >\n <span>{model}</span>\n <svg viewBox=\"0 0 16 16\" width=\"12\" height=\"12\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><path d=\"M8 10.5L4 6h8z\"/></svg>\n </button>\n {modelOpen ? (\n <div className={css.modelMenuList} role=\"listbox\" aria-label={tt('model.label')}>\n {imageModels.map(option => (\n <button\n key={option}\n type=\"button\"\n role=\"option\"\n aria-selected={model === option}\n className={css.modelMenuItem}\n data-selected={model === option ? '' : undefined}\n onClick={() => { setModel(option); setModelOpen(false) }}\n >\n {option}\n </button>\n ))}\n </div>\n ) : null}\n </span>\n </label>\n <div className={css.compareControl}>\n <label className={css.compareToggle}>\n <input type=\"checkbox\" checked={compareEnabled} onChange={event => { setCompareEnabled(event.target.checked) }} />\n <span>{tt('compare.enable')}</span>\n </label>\n {compareEnabled ? (\n <div className={css.compareModelChoices} role=\"group\" aria-label={tt('compare.models')}>\n {imageModels.map(option => (\n <label key={option}>\n <input type=\"checkbox\" checked={compareModels.includes(option)} onChange={() => { setCompareModels(previous => previous.includes(option) ? previous.filter(value => value !== option) : [...previous, option]) }} />\n <span>{option}</span>\n </label>\n ))}\n </div>\n ) : null}\n </div>\n <Button\n variant=\"primary\"\n size=\"md\"\n className={css.generateButton}\n disabled={generateDisabled}\n onClick={() => { void handleGenerate() }}\n >\n {generating ? (\n <span className={css.generateInner}>\n <span className={css.spinner} />\n {tt('generating')}\n </span>\n ) : tt('generate')}\n </Button>\n </section>\n </aside>\n\n {/* --------------------------------------------------------- canvas */}\n <section className={css.canvas} data-gallery={tab === 'gallery' ? 'true' : undefined}>\n {tab === 'gallery' ? (\n <div className={css.galleryWorkspace}>\n <header className={css.galleryToolbar}>\n <div>\n <h3 className={css.galleryHeading}>{tt('gallery.all')}</h3>\n <span className={css.galleryCount}>{tt('gallery.count', { count: filteredGallery.length })}</span>\n </div>\n <div className={css.galleryToolbarActions}>\n <input className={css.gallerySearch} value={galleryQuery} onChange={event => { setGalleryQuery(event.target.value) }} placeholder={tt('gallery.search')} aria-label={tt('gallery.search')} />\n <button type=\"button\" className={css.gallerySelectMode} data-active={gallerySelecting ? '' : undefined} aria-pressed={gallerySelecting} onClick={() => { setGallerySelecting(previous => !previous) }}>\n {gallerySelecting ? tt('gallery.selectionDone') : tt('gallery.select')}\n </button>\n <div className={css.galleryViewToggle} role=\"group\" aria-label={tt('gallery.viewMode')}>\n <button type=\"button\" data-active={galleryView === 'masonry' ? '' : undefined} onClick={() => { setGalleryView('masonry') }} title={tt('gallery.masonry')}>\n <span aria-hidden=\"true\">▦</span> {tt('gallery.masonry')}\n </button>\n <button type=\"button\" data-active={galleryView === 'grid' ? '' : undefined} onClick={() => { setGalleryView('grid') }} title={tt('gallery.grid')}>\n <span aria-hidden=\"true\">▤</span> {tt('gallery.grid')}\n </button>\n </div>\n <select className={css.gallerySort} value={gallerySort} onChange={event => { setGallerySort(event.target.value as 'newest' | 'oldest') }} aria-label={tt('gallery.sort')}>\n <option value=\"newest\">{tt('gallery.newest')}</option>\n <option value=\"oldest\">{tt('gallery.oldest')}</option>\n </select>\n {gallery.length > 0 ? <button type=\"button\" className={css.galleryClear} onClick={() => { void clearGalleryAll() }}>{tt('gallery.clear')}</button> : null}\n </div>\n </header>\n {selectedGalleryIds.size > 0 ? (\n <section className={css.gallerySelectionBar} aria-label={tt('gallery.selected', { count: selectedGalleryIds.size })}>\n <strong>{tt('gallery.selected', { count: selectedGalleryIds.size })}</strong>\n <input className={css.galleryTagInput} value={galleryTagInput} onChange={event => { setGalleryTagInput(event.target.value) }} placeholder={tt('gallery.tagsPlaceholder')} aria-label={tt('gallery.tagsPlaceholder')} />\n <button type=\"button\" className={css.galleryBulkButton} disabled={galleryTagInput.trim() === ''} onClick={() => { void applyGalleryTags() }}>{tt('gallery.tagsApply')}</button>\n <button type=\"button\" className={css.galleryBulkButton} onClick={downloadGalleryImages}>{tt('gallery.downloadSelected')}</button>\n <button type=\"button\" className={css.galleryBulkButton} onClick={exportGalleryJson}>{tt('gallery.exportJson')}</button>\n <button type=\"button\" className={css.gallerySelectionClear} onClick={clearGallerySelection}>{tt('gallery.selectionClear')}</button>\n </section>\n ) : null}\n {filteredGallery.length === 0 ? (\n <div className={css.historyEmpty}>{tt('gallery.empty')}</div>\n ) : (\n <div className={css.galleryMasonry} data-view={galleryView}>\n {filteredGallery.map(entry => {\n const image = entry.images[0]\n if (image === undefined) return null\n return (\n <article key={entry.id} className={css.galleryCard} data-selected={selectedGalleryIds.has(entry.id) ? '' : undefined}>\n <label className={css.gallerySelect} title={tt('gallery.select')}>\n <input type=\"checkbox\" checked={selectedGalleryIds.has(entry.id)} onChange={() => { setGallerySelecting(true); toggleGallerySelection(entry.id) }} />\n </label>\n <button type=\"button\" className={css.galleryImageButton} data-selecting={gallerySelecting ? '' : undefined} onClick={() => { if (gallerySelecting) toggleGallerySelection(entry.id); else void viewGalleryEntry(entry) }} title={gallerySelecting ? tt('gallery.select') : tt('preview.open')}>\n <img className={css.galleryImage} src={image.url} alt={entry.prompt} />\n <span className={css.galleryBadge}>{entry.mode === 'edit' ? tt('mode.edit') : tt('mode.text')}</span>\n </button>\n <div className={css.galleryCardFooter}>\n <span className={css.galleryAvatar}>{entry.model.startsWith('grok') ? 'G' : 'D'}</span>\n <span className={css.galleryCardInfo}>\n <strong>{entry.prompt || tt('gallery.untitled')}</strong>\n <small>{entry.model} · {normalizeSize(entry.size)} · {formatTime(entry.createdAt)}</small>\n <span className={css.galleryTags}>\n {(entry.tags ?? []).map(tag => <button key={tag} type=\"button\" onClick={() => { setGalleryTagFilter(tag) }}>{tag}</button>)}\n <button type=\"button\" className={css.galleryTagEdit} onClick={() => { startEditingGalleryTags(entry) }} title={tt('gallery.editTags')}>{tt('gallery.tagsEditShort')}</button>\n </span>\n </span>\n <button type=\"button\" className={css.galleryRemove} onClick={() => { void deleteGalleryEntry(entry.id) }} title={tt('gallery.delete')}>×</button>\n </div>\n {editingGalleryTagsId === entry.id ? (\n <form className={css.galleryTagEditor} onSubmit={event => { event.preventDefault(); void saveGalleryTags(entry.id) }}>\n <input value={galleryTagEditInput} onChange={event => { setGalleryTagEditInput(event.target.value) }} placeholder={tt('gallery.tagsPlaceholder')} aria-label={tt('gallery.tagsPlaceholder')} autoFocus />\n <button type=\"submit\">{tt('gallery.tagsSave')}</button>\n <button type=\"button\" onClick={() => { setEditingGalleryTagsId(null); setGalleryTagEditInput('') }}>{tt('gallery.tagsCancel')}</button>\n </form>\n ) : null}\n </article>\n )\n })}\n </div>\n )}\n </div>\n ) : null}\n {tab !== 'gallery' && tasks.length > 0 ? (\n <section className={css.taskTray} data-open={taskTrayOpen ? 'true' : 'false'} aria-label={tt('tasks.title')}>\n <header className={css.taskTrayHeader}>\n <button type=\"button\" className={css.taskTrayToggle} aria-expanded={taskTrayOpen} onClick={() => { setTaskTrayOpen(open => !open) }}>\n <span>{tt('tasks.title')}</span>\n <span className={css.taskTrayCount}>{tasks.filter(task => task.status === 'queued' || task.status === 'running').length}</span>\n <span className={css.taskTrayChevron} aria-hidden=\"true\">{taskTrayOpen ? '⌃' : '⌄'}</span>\n </button>\n {taskTrayOpen ? <button type=\"button\" className={css.taskTrayClose} aria-label={tt('preview.close')} onClick={() => { setTaskTrayOpen(false) }}>×</button> : null}\n </header>\n <div className={css.taskRows}>\n {tasks.slice(0, 5).map(task => (\n <div key={task.id} className={css.taskRow} data-status={task.status}>\n <span className={css.taskStatus}>{tt(`tasks.${task.status}` as never)}</span>\n <span className={css.taskPrompt}>{task.request.prompt}</span>\n {(task.status === 'queued' || task.status === 'running') ? <button type=\"button\" onClick={() => { void api.taskCancel(task.id) }}>{tt('tasks.cancel')}</button> : null}\n {task.status === 'failed' || task.status === 'cancelled' ? <button type=\"button\" onClick={() => { void api.taskRetry(task.id) }}>{tt('tasks.retry')}</button> : null}\n </div>\n ))}\n </div>\n </section>\n ) : null}\n {tab !== 'gallery' && comparison !== null ? (\n <section className={css.comparisonBoard} aria-label={tt('compare.title')}>\n <header><div><strong>{tt('compare.title')}</strong><span>{comparisonResults.length} / {comparisonTasks.length}</span></div><button type=\"button\" disabled={comparisonResults.length === 0} onClick={() => { setComparisonFullscreen(true) }}>{tt('compare.fullscreen')}</button></header>\n <div className={css.comparisonGrid}>\n {comparisonTasks.map(task => (\n <article key={task.id}>\n <strong>{task.request.model}</strong>\n {task.result?.images[0] !== undefined ? <img src={srcOf(task.result.images[0])} alt={task.request.model} /> : <span>{tt(`tasks.${task.status}` as never)}</span>}\n </article>\n ))}\n </div>\n </section>\n ) : null}\n {generating ? (\n <div className={css.canvasState} role=\"status\">\n <span className={css.bigSpinner} />\n <span className={css.canvasStateTitle}>{tt('canvas.generating')}</span>\n <span className={css.canvasStateHint}>{tt('canvas.elapsed', { seconds: elapsed })}</span>\n </div>\n ) : null}\n\n {!generating && error !== null ? (\n <div className={css.canvasError} role=\"alert\">{tt('canvas.error', { error })}</div>\n ) : null}\n\n {!generating && !error && images.length === 0 ? (\n <div className={css.canvasState}>\n <span className={css.canvasEmptyIcon}>\n <svg viewBox=\"0 0 24 24\" width=\"34\" height=\"34\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"3\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><path d=\"M21 15l-5-5L5 21\"/></svg>\n </span>\n <span className={css.canvasStateTitle}>{tt('canvas.emptyTitle')}</span>\n <span className={css.canvasStateHint}>{tt('canvas.emptyHint')}</span>\n </div>\n ) : null}\n\n {!generating && images.length > 0 ? (\n <div className={css.canvasBody}>\n <div className={css.canvasMeta}>\n <span>{tt('canvas.images', { count: images.length })}</span>\n {viewingEntry !== null || viewingGalleryEntry !== null ? (\n <span className={css.canvasHistoryTag}>\n {viewingEntry !== null\n ? tt('history.viewing', { time: formatTime(viewingEntry.createdAt) })\n : tt('gallery.viewing', { time: formatTime(viewingGalleryEntry!.createdAt) })}\n </span>\n ) : null}\n </div>\n <div className={css.grid} data-count={images.length}>\n {images.map((image, index) => (\n <figure\n key={index}\n className={css.imageCard}\n role=\"button\"\n tabIndex={0}\n title={tt('preview.open')}\n onClick={() => { openPreview(images, index) }}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n openPreview(images, index)\n }\n }}\n >\n <img\n className={css.image}\n src={srcOf(image)}\n alt={image.revisedPrompt ?? `${tt('panel.title')} ${index + 1}`}\n />\n {image.revisedPrompt !== undefined ? (\n <figcaption className={css.imageCaption} title={image.revisedPrompt}>\n {tt('revisedPrompt', { prompt: image.revisedPrompt })}\n </figcaption>\n ) : null}\n <span className={css.zoomHint}>\n <svg viewBox=\"0 0 16 16\" width=\"13\" height=\"13\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.4\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><circle cx=\"7\" cy=\"7\" r=\"4\"/><path d=\"M13 13l-3.2-3.2\"/><path d=\"M7 5.4v3.2M5.4 7h3.2\"/></svg>\n {tt('preview.open')}\n </span>\n <button\n type=\"button\"\n className={css.galleryAdd}\n title={tt('gallery.add')}\n disabled={galleryAdding}\n onClick={(event) => { event.stopPropagation(); void addToGallery(image) }}\n >\n <svg viewBox=\"0 0 16 16\" width=\"12\" height=\"12\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><rect x=\"2.5\" y=\"3\" width=\"11\" height=\"10\" rx=\"1.5\"/><path d=\"M8 5.8v4.4M5.8 8h4.4\"/></svg>\n {tt('gallery.add')}\n </button>\n <a\n className={css.download}\n href={srcOf(image)}\n download={`dsh-image-${index + 1}.${extensionOf(image.mime)}`}\n onClick={(event) => { event.stopPropagation() }}\n >\n {tt('download')}\n </a>\n </figure>\n ))}\n </div>\n </div>\n ) : null}\n </section>\n\n {/* ------------------------ right column: gallery (tab) or history */}\n {tab === 'gallery' ? (\n <aside className={css.history}>\n <header className={css.historyHeader}>\n <span className={css.historyTitle}>{tt('gallery.title')}</span>\n {gallery.length > 0 ? (\n <button type=\"button\" className={css.historyClear} onClick={() => { void clearGalleryAll() }}>\n {tt('gallery.clear')}\n </button>\n ) : null}\n </header>\n\n {gallery.length === 0 ? (\n <div className={css.historyEmpty}>{tt('gallery.empty')}</div>\n ) : (\n <div className={css.historyList}>\n {gallery.map(entry => (\n <div\n key={entry.id}\n className={css.historyItem}\n data-active={entry.id === galleryViewingId ? '' : undefined}\n >\n <button\n type=\"button\"\n className={css.historyMain}\n onClick={() => { void viewGalleryEntry(entry) }}\n >\n {entry.images.length > 0 ? (\n <img className={css.historyThumb} src={entry.images[0]!.url} alt=\"\" />\n ) : (\n <span className={css.historyThumbPlaceholder} />\n )}\n <span className={css.historyInfo}>\n <span className={css.historyPrompt}>{entry.prompt}</span>\n <span className={css.historyMeta}>\n {tt(`mode.${entry.mode === 'edit' ? 'edit' : 'text'}` as const)}\n {' · '}{formatTime(entry.createdAt)}\n </span>\n </span>\n </button>\n <span className={css.historyActions}>\n <button type=\"button\" className={css.historyAction} onClick={() => { void restoreGalleryEntry(entry) }}>\n {tt('history.restore')}\n </button>\n <button type=\"button\" className={css.historyAction} data-danger onClick={() => { void deleteGalleryEntry(entry.id) }}>\n {tt('gallery.delete')}\n </button>\n </span>\n </div>\n ))}\n </div>\n )}\n </aside>\n ) : (\n <aside className={css.history}>\n <header className={css.historyHeader}>\n <span className={css.historyTitle}>{tt('history.title')}</span>\n {history.length > 0 ? (\n <button type=\"button\" className={css.historyClear} onClick={() => { void clearHistory() }}>\n {tt('history.clear')}\n </button>\n ) : null}\n </header>\n\n <div className={css.historyFilters}>\n <input className={css.historySearch} value={historyQuery} onChange={event => { setHistoryQuery(event.target.value) }} placeholder={tt('history.search')} aria-label={tt('history.search')} />\n <select value={historyModelFilter} onChange={event => { setHistoryModelFilter(event.target.value) }} aria-label={tt('history.model')}>\n <option value=\"all\">{tt('history.allModels')}</option>\n {[...new Set(history.map(entry => entry.model))].map(option => <option key={option} value={option}>{option}</option>)}\n </select>\n <select value={historyRatioFilter} onChange={event => { setHistoryRatioFilter(event.target.value) }} aria-label={tt('history.ratio')}>\n <option value=\"all\">{tt('history.allRatios')}</option>\n {[...new Set(history.map(entry => normalizeSize(entry.size)))].map(option => <option key={option} value={option}>{option}</option>)}\n </select>\n </div>\n\n {filteredHistory.length === 0 ? (\n <div className={css.historyEmpty}>{tt('history.empty')}</div>\n ) : (\n <div className={css.historyList}>\n {filteredHistory.map(entry => (\n <div\n key={entry.id}\n className={css.historyItem}\n data-active={entry.id === viewingHistoryId ? '' : undefined}\n >\n <button\n type=\"button\"\n className={css.historyMain}\n onClick={() => { void viewHistoryEntry(entry) }}\n >\n {entry.images.length > 0 ? (\n <img className={css.historyThumb} src={entry.images[0]!.url} alt=\"\" />\n ) : (\n <span className={css.historyThumbPlaceholder} />\n )}\n <span className={css.historyInfo}>\n <span className={css.historyPrompt}>{entry.prompt}</span>\n <span className={css.historyMeta}>\n {tt(`mode.${entry.mode === 'edit' ? 'edit' : 'text'}` as const)}\n {' · '}{formatTime(entry.createdAt)}\n {' · '}{entry.images.length} {tt('history.images')}\n </span>\n </span>\n </button>\n <span className={css.historyActions}>\n {entry.images.length > 0 ? (\n <button\n type=\"button\"\n className={css.historyAction}\n disabled={galleryAdding}\n title={tt('gallery.add')}\n onClick={() => { void addHistoryEntryToGallery(entry) }}\n >\n {tt('gallery.add')}\n </button>\n ) : null}\n <button type=\"button\" className={css.historyAction} onClick={() => { void restoreHistoryEntry(entry) }}>\n {tt('history.restore')}\n </button>\n <button type=\"button\" className={css.historyAction} data-danger onClick={() => { void deleteHistoryEntry(entry.id) }}>\n {tt('history.delete')}\n </button>\n </span>\n </div>\n ))}\n </div>\n )}\n </aside>\n )}\n </div>\n\n {/* ------------------------------------------------ template library */}\n {libraryOpen ? (\n <TemplateLibrary\n api={api}\n onClose={() => { setLibraryOpen(false) }}\n onUse={(text) => {\n setTab('text')\n setPrompt(text)\n setError(null)\n setLibraryOpen(false)\n }}\n />\n ) : null}\n\n {configGuide !== null ? (\n <div className={css.configGuide} role=\"dialog\" aria-modal=\"true\" aria-label={tt(`config.${configGuide}Title` as never)}>\n <div className={css.configGuideBody}>\n <strong>{tt(`config.${configGuide}Title` as never)}</strong>\n <span>{tt(`config.${configGuide}Hint` as never)}</span>\n <button type=\"button\" onClick={() => { setConfigGuide(null) }}>{tt('preview.close')}</button>\n </div>\n </div>\n ) : null}\n\n {comparisonFullscreen && comparison !== null ? createPortal(\n <div className={css.comparisonFullscreen} role=\"dialog\" aria-modal=\"true\" aria-label={tt('compare.title')} onClick={() => { setComparisonFullscreen(false) }}>\n <button type=\"button\" className={css.lightboxClose} aria-label={tt('preview.close')} onClick={() => { setComparisonFullscreen(false) }}>×</button>\n <div className={css.comparisonFullscreenGrid} onClick={event => { event.stopPropagation() }}>\n {comparisonResults.map(task => (\n <figure key={task.id}><figcaption>{task.request.model}</figcaption>{task.result!.images.map((image, index) => <img key={index} src={srcOf(image)} alt={task.request.model} />)}</figure>\n ))}\n </div>\n </div>, document.body) : null}\n\n {/* -------------------------------------------------- preview overlay */}\n {preview !== null && previewImage !== null\n ? createPortal(\n <div\n className={css.lightbox}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={tt('preview.title')}\n onClick={closePreview}\n >\n <button type=\"button\" className={css.lightboxClose} aria-label={tt('preview.close')} title={tt('preview.close')} onClick={closePreview}>\n <svg viewBox=\"0 0 16 16\" width=\"18\" height=\"18\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" aria-hidden=\"true\"><path d=\"M4 4l8 8M12 4l-8 8\"/></svg>\n </button>\n {preview.images.length > 1 ? (\n <>\n <button type=\"button\" className={css.lightboxNav} data-dir=\"prev\" aria-label={tt('preview.prev')} onClick={(event) => { event.stopPropagation(); stepPreview(-1) }}>\n <svg viewBox=\"0 0 16 16\" width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><path d=\"M10 3l-5 5 5 5\"/></svg>\n </button>\n <button type=\"button\" className={css.lightboxNav} data-dir=\"next\" aria-label={tt('preview.next')} onClick={(event) => { event.stopPropagation(); stepPreview(1) }}>\n <svg viewBox=\"0 0 16 16\" width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 3l5 5-5 5\"/></svg>\n </button>\n </>\n ) : null}\n <figure className={css.lightboxFigure} onClick={(event) => { event.stopPropagation() }}>\n <div\n ref={previewStage}\n className={css.lightboxStage}\n onWheel={(event) => {\n event.preventDefault()\n setPreviewScale(current => clampPreviewScale(current + (event.deltaY < 0 ? PREVIEW_SCALE_STEP : -PREVIEW_SCALE_STEP)))\n }}\n >\n <div\n className={css.lightboxScaleFrame}\n style={{ width: `${previewFrameScale * 100}%`, height: `${previewFrameScale * 100}%` }}\n >\n <img\n className={css.lightboxImage}\n style={{ width: `${previewImageScale * 100}%`, height: `${previewImageScale * 100}%` }}\n src={srcOf(previewImage)}\n alt={previewImage.revisedPrompt ?? tt('preview.title')}\n />\n </div>\n </div>\n <div className={css.lightboxTools} role=\"group\" aria-label={tt('preview.zoomControls')}>\n <button type=\"button\" className={css.lightboxTool} aria-label={tt('preview.zoomOut')} title={tt('preview.zoomOut')} onClick={() => { setPreviewScale(current => clampPreviewScale(current - PREVIEW_SCALE_STEP)) }}>\n <svg viewBox=\"0 0 16 16\" width=\"17\" height=\"17\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.7\" strokeLinecap=\"round\" aria-hidden=\"true\"><circle cx=\"7\" cy=\"7\" r=\"4.2\"/><path d=\"M4.8 7h4.4M13 13l-2.8-2.8\"/></svg>\n </button>\n <button type=\"button\" className={css.lightboxZoomLevel} aria-label={tt('preview.zoomReset')} title={tt('preview.zoomReset')} onClick={() => { setPreviewScale(1) }}>\n {tt('preview.zoomLevel', { percent: Math.round(previewScale * 100) })}\n </button>\n <button type=\"button\" className={css.lightboxTool} aria-label={tt('preview.zoomIn')} title={tt('preview.zoomIn')} onClick={() => { setPreviewScale(current => clampPreviewScale(current + PREVIEW_SCALE_STEP)) }}>\n <svg viewBox=\"0 0 16 16\" width=\"17\" height=\"17\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.7\" strokeLinecap=\"round\" aria-hidden=\"true\"><circle cx=\"7\" cy=\"7\" r=\"4.2\"/><path d=\"M7 4.8v4.4M4.8 7h4.4M13 13l-2.8-2.8\"/></svg>\n </button>\n </div>\n {previewImage.revisedPrompt !== undefined ? (\n <div className={css.lightboxCaptionRow}>\n <figcaption className={css.lightboxCaption} title={previewImage.revisedPrompt}>\n {tt('revisedPrompt', { prompt: previewImage.revisedPrompt })}\n </figcaption>\n <button type=\"button\" className={css.lightboxCopy} aria-label={tt(promptCopied ? 'preview.copied' : 'preview.copyPrompt')} title={tt(promptCopied ? 'preview.copied' : 'preview.copyPrompt')} onClick={() => { void copyPreviewPrompt(previewImage.revisedPrompt!) }}>\n {promptCopied ? (\n <svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 8l3 3 7-7\"/></svg>\n ) : (\n <svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><rect x=\"5\" y=\"5\" width=\"7\" height=\"8\" rx=\"1\"/><path d=\"M3 10V3.8c0-.44.36-.8.8-.8H9\"/></svg>\n )}\n <span>{tt(promptCopied ? 'preview.copied' : 'preview.copyPrompt')}</span>\n </button>\n </div>\n ) : null}\n <div className={css.lightboxMeta}>\n <span className={css.lightboxIndex}>{tt('preview.index', { index: preview.index + 1, total: preview.images.length })}</span>\n <span className={css.lightboxActions}>\n <button type=\"button\" className={css.lightboxEdit} disabled={galleryAdding} onClick={() => { void addToGallery(previewImage) }}>\n {tt('gallery.add')}\n </button>\n <button type=\"button\" className={css.lightboxEdit} onClick={addPreviewToEdit}>\n {tt('preview.addToEdit')}\n </button>\n <a\n className={css.lightboxDownload}\n href={srcOf(previewImage)}\n download={`dsh-image-${preview.index + 1}.${extensionOf(previewImage.mime)}`}\n >\n {tt('download')}\n </a>\n </span>\n </div>\n </figure>\n </div>,\n document.body,\n )\n : null}\n\n {/* ------------------------------------------------- gallery toast */}\n {galleryMessage !== null ? (\n <div className={css.galleryToast} role=\"status\">\n <svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><rect x=\"2.5\" y=\"3\" width=\"11\" height=\"10\" rx=\"1.5\"/><path d=\"M8 5.8v4.4M5.8 8h4.4\"/></svg>\n {galleryMessage}\n </div>\n ) : null}\n </div>\n )\n}\n\n/** File extension for a MIME type (download filenames). */\nfunction extensionOf(mime: string): string {\n switch (mime.split(';')[0]!.trim()) {\n case 'image/jpeg': return 'jpg'\n case 'image/webp': return 'webp'\n case 'image/gif': return 'gif'\n default: return 'png'\n }\n}\n","/**\n * Panel view mounting.\n *\n * The `conversation` slot is single-occupant (ui-conversation) and external\n * plugins cannot declare slots, so the panel takes over the center column at\n * the DOM level: a container is appended inside the conversation grid item\n * (an extra trailing child React never manages), and a stylesheet rule hides\n * the conversation content while the panel is active. Toggling is a data\n * attribute on <html> — no React involvement, so the conversation subtree\n * underneath stays mounted and stateful.\n *\n * Shell compatibility: the center column is `[data-pane=\"conversation\"]` on\n * legacy shells and `[class*=\"centerCol\"]` on the rc.6+ AppFrame layout (the\n * same dual selector the dsh-ssh / task-board panels use); both are queried\n * and both get the `position: relative` base in panel.module.css.\n */\n\nimport { createRoot, type Root } from 'react-dom/client'\nimport type { ImageGenApi } from './api.ts'\nimport type { ImageGenController } from './controller.ts'\nimport { ImageGenPanel } from './ImageGenPanel.tsx'\nimport type { ImageGenScope } from './settings-scope.ts'\nimport css from './panel.module.css'\n\n/** The injected panel container (kept in the DOM, hidden when inactive). */\nexport const PANEL_VIEW_SELECTOR = '[data-dsh-imagegen-view]'\n\nconst CONVERSATION_COLUMN_SELECTOR = '[data-pane=\"conversation\"], [class*=\"centerCol\"]'\nconst ACTIVE_ATTR = 'data-dsh-imagegen-active'\n/** Sibling panels' activation attributes, removed when this panel opens. */\nconst OTHER_ACTIVE_ATTRS = ['data-dsh-taskboard-active', 'data-dsh-ssh-active']\n/** Cross-plugin activation event; detail is the activating panel name. */\nconst ACTIVATE_EVENT = 'dsh-panel-activate'\nconst PANEL_NAME = 'imagegen'\n\n/** Find the center column, or undefined while the frame is not mounted. */\nfunction conversationColumn(): HTMLElement | undefined {\n return document.querySelector<HTMLElement>(CONVERSATION_COLUMN_SELECTOR) ?? undefined\n}\n\n/**\n * Mount the panel React tree into the center column and bind its visibility\n * to the controller's panelOpen state.\n * @param controller - the panel controller driving the view.\n * @param api - the image-generation API client the panel operates through.\n * @param scope - the settings scope (config status banner).\n * @returns disposer unmounting the tree and restoring the column.\n */\nexport function mountPanel(\n controller: ImageGenController,\n api: ImageGenApi,\n scope: ImageGenScope,\n): () => void {\n let root: Root | undefined\n let container: HTMLDivElement | undefined\n\n const ensure = (): void => {\n if (container !== undefined) {\n if (container.isConnected) return\n // The conversation pane was replaced; drop the stale tree and remount.\n root?.unmount()\n root = undefined\n container.remove()\n container = undefined\n }\n const column = conversationColumn()\n if (column === undefined) return\n container = document.createElement('div')\n container.dataset.dshImagegenView = ''\n container.className = css.view\n column.appendChild(container)\n root = createRoot(container)\n root.render(<ImageGenPanel api={api} scope={scope} />)\n }\n\n // The frame mounts after boot settlement; watch for the column's arrival.\n const waitObserver = new MutationObserver(() => { ensure() })\n waitObserver.observe(document.body, { childList: true, subtree: true })\n\n const applyActive = (): void => {\n if (controller.getSnapshot().panelOpen) {\n // Single-occupant center column: opening this panel must evict sibling\n // panels (task board / ssh), both their html attributes and their\n // controller states, otherwise the visibility rules fight.\n for (const attr of OTHER_ACTIVE_ATTRS) document.documentElement.removeAttribute(attr)\n document.documentElement.setAttribute(ACTIVE_ATTR, '')\n document.dispatchEvent(new CustomEvent(ACTIVATE_EVENT, { detail: PANEL_NAME }))\n } else {\n document.documentElement.removeAttribute(ACTIVE_ATTR)\n }\n }\n const onOtherActivate = (event: Event): void => {\n const detail = (event as CustomEvent).detail\n if ((detail === 'ssh' || detail === 'taskboard') && controller.getSnapshot().panelOpen) {\n controller.close()\n }\n }\n // Jump out on sidebar context clicks: clicking a session/workspace row\n // hands the center column back to the conversation. Capture phase.\n const SIDEBAR_ROW_SELECTOR = '[class*=\"sessionRow\"], [class*=\"projectRow\"], [class*=\"searchResultRow\"], [class*=\"searchResultWorkspace\"], [class*=\"newSession\"]'\n const onClickSidebarRow = (event: MouseEvent): void => {\n if (!controller.getSnapshot().panelOpen) return\n const target = event.target as HTMLElement | null\n if (target === null) return\n if (target.closest(SIDEBAR_ROW_SELECTOR) !== null) controller.close()\n }\n document.addEventListener('click', onClickSidebarRow, true)\n document.addEventListener(ACTIVATE_EVENT, onOtherActivate)\n const unsubscribe = controller.subscribe(applyActive)\n applyActive()\n ensure()\n\n return () => {\n document.removeEventListener('click', onClickSidebarRow, true)\n document.removeEventListener(ACTIVATE_EVENT, onOtherActivate)\n waitObserver.disconnect()\n unsubscribe()\n document.documentElement.removeAttribute(ACTIVE_ATTR)\n root?.unmount()\n root = undefined\n container?.remove()\n container = undefined\n }\n}\n","/**\n * Sidebar entry injection.\n *\n * dsh's sidebar shell exposes no slot an external plugin can register into,\n * so — following the dsh-ssh / task-board precedent of DOM-level extension —\n * the entry row is injected after the shell's New Session button (after the\n * sibling plugin family block). The injection self-heals: a MutationObserver\n * watches the sidebar root and re-inserts the row whenever a React re-render\n * displaces it (re-insertion happens in the same frame, before paint).\n *\n * The row is plain DOM (no React tree) so it can never disturb the shell's\n * reconciliation; the panel view it toggles is a separate React root mounted\n * in the center column (see mount.tsx).\n */\n\nimport type { ImageGenController } from './controller.ts'\nimport css from './panel.module.css'\n\n/** Stable data attribute identifying the injected entry row. */\nexport const ENTRY_SELECTOR = '[data-dsh-imagegen-entry]'\n\n/** Inline icon (matches the shell's 16px nav-icon look): a picture glyph. */\nconst ICON = '<svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"2\" y=\"2.5\" width=\"12\" height=\"11\" rx=\"1.5\"/><circle cx=\"5.6\" cy=\"5.8\" r=\"1\"/><path d=\"M2.5 12.5l3.6-3.4 2.4 2.2 3-3 2 2.4\"/></svg>'\n\n/** Family entry selectors of sibling plugins (relative placement anchor). */\nconst FAMILY_ENTRY_SELECTOR = '[data-dsh-taskboard-entry], [data-dsh-ssh-entry], [data-dsh-imagegen-entry]'\n\n/** Find the sidebar shell root element, or undefined while not yet mounted. */\nfunction sidebarRoot(): HTMLElement | undefined {\n const column = document.querySelector<HTMLElement>('[data-pane=\"sidebar\"], [class*=\"sidebarCol\"]')\n if (column === null) return undefined\n const logoOwner = column.querySelector<HTMLElement>('[class*=\"logoRow\"]')?.parentElement\n return logoOwner ?? (column.firstElementChild as HTMLElement | undefined)\n}\n\n/** The New Session button: nested in the logo row on current shells, a direct child on legacy shells. */\nfunction newSessionButton(root: HTMLElement): HTMLButtonElement | undefined {\n const nested = root.querySelector<HTMLButtonElement>('button[class*=\"newSession\"]')\n if (nested !== null) return nested\n for (const child of root.children) {\n if (child.tagName === 'BUTTON') return child as HTMLButtonElement\n }\n return undefined\n}\n\n/** Build the entry row (a detached button; insert once the shell is up). */\nfunction createEntry(controller: ImageGenController, label: string, tooltip: string): HTMLButtonElement {\n const entry = document.createElement('button')\n entry.type = 'button'\n entry.dataset.dshImagegenEntry = ''\n entry.className = css.entry\n entry.setAttribute('aria-label', label)\n entry.setAttribute('title', tooltip)\n entry.innerHTML = '<span class=\"' + css.entryIcon + '\">' + ICON + '</span><span class=\"' + css.entryLabel + '\">' + label + '</span>'\n entry.addEventListener('click', () => { controller.toggle() })\n return entry\n}\n\n/** Re-insert the entry after the family block (task board → ssh → imagegen). */\nfunction placeEntry(root: HTMLElement, entry: HTMLButtonElement): boolean {\n const button = newSessionButton(root)\n if (button === undefined) return false\n if (entry.parentElement !== root) {\n // Position relative to the family block, never relative to transient\n // logoRow geometry: every family plugin that self-heals during a\n // re-render then lands in the same relative order.\n const row = button.closest('[class*=\"logoRow\"]')\n const base = (row !== null && row.parentElement === root) ? row : button\n const family = Array.from(root.children).filter(\n (el): el is HTMLElement => el instanceof HTMLElement && el.matches(FAMILY_ENTRY_SELECTOR),\n )\n const anchor = family.length > 0 ? family[family.length - 1].nextElementSibling : base.nextElementSibling\n root.insertBefore(entry, anchor)\n }\n return true\n}\n\n/**\n * Mount the sidebar entry, waiting for the shell to render and self-healing\n * on later React re-renders.\n * @param controller - the panel controller the entry toggles.\n * @param label - the entry label (localized).\n * @param tooltip - the entry tooltip (localized).\n * @returns disposer removing the entry and its observers.\n */\nexport function mountSidebarEntry(controller: ImageGenController, label: string, tooltip: string): () => void {\n const entry = createEntry(controller, label, tooltip)\n let root: HTMLElement | undefined\n let placed = false\n\n const tryPlace = (): void => {\n if (root !== undefined && !root.isConnected) {\n rootObserver.disconnect()\n root = undefined\n placed = false\n }\n if (placed) {\n if (document.body.contains(entry)) return\n rootObserver.disconnect()\n root = undefined\n placed = false\n }\n root ??= sidebarRoot()\n if (root === undefined) return\n placed = placeEntry(root, entry)\n if (placed) {\n rootObserver.observe(root, { childList: true, subtree: true })\n }\n }\n\n // Body-level watcher retained as the \"whole rebuild\" fallback.\n const waitObserver = new MutationObserver(() => { tryPlace() })\n waitObserver.observe(document.body, { childList: true, subtree: true })\n\n // Self-heal: if a React re-render displaces the row, re-insert it in the\n // same frame (microtask before paint -> no visible flicker).\n const rootObserver = new MutationObserver(() => {\n if (root === undefined || !root.isConnected) {\n placed = false\n tryPlace()\n return\n }\n if (!root.contains(entry)) {\n placed = placeEntry(root, entry)\n }\n })\n\n // Reflect the panel's open state on the row (active highlight).\n const syncActive = () => {\n if (controller.getSnapshot().panelOpen) entry.dataset.active = 'true'\n else delete entry.dataset.active\n }\n const unsubscribe = controller.subscribe(syncActive)\n syncActive()\n\n tryPlace()\n\n return () => {\n waitObserver.disconnect()\n rootObserver.disconnect()\n unsubscribe()\n entry.remove()\n }\n}\n","/**\n * Staged form model behind the plugin settings card. A card stages what the\n * user types and writes it only when they save — the settings write is a\n * durable, revision-fenced document mutation, so staging keeps what is on\n * screen exactly what a save would store. Self-contained slice of the same\n * pattern the dsh-web-ui family cards use (this package must not depend on a\n * sibling UI package).\n */\n\nimport { createSnapshotStore, type SettingsScope, type SettingsScopeSnapshot, type SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'\n\n/** The write one field's staged text performs when the card is saved. */\nexport type FieldWrite =\n | { kind: 'set'; value: unknown }\n | { kind: 'clear' }\n\n/** How one field converts between its stored value and its draft text. */\nexport interface FieldSpec {\n /** Field name inside the namespace section. */\n field: string\n /** Render a stored value as draft text; the empty string when the section carries none. */\n format: (value: unknown) => string\n /**\n * The write this draft text stages, or undefined when the text is not a\n * value this field accepts — which blocks the save rather than discarding it.\n */\n parse: (text: string) => FieldWrite | undefined\n /**\n * True for secret fields (role('secret') in the namespace schema): the\n * redacted wire view never returns the stored value, so the form treats an\n * empty draft as \"no change\" and judges writes by the namespace's secrets\n * sidecar instead of the user layer.\n */\n secret?: boolean\n}\n\n/** One field as the card renders it. */\nexport interface FieldState {\n /** Draft text the control renders. */\n text: string\n /** Whether saving would leave a user-layer entry for this field. */\n overridden: boolean\n /** Whether the draft is not a value this field accepts, which blocks saving. */\n invalid: boolean\n}\n\n/** Form state every plugin settings card shares. */\nexport interface CardShell {\n /** False while the namespace is still loading; the card renders nothing. */\n available: boolean\n /** Whether the namespace is actually served (the bridge answered). */\n exposed: boolean\n /** Whether the Host document accepts writes. */\n writable: boolean\n /** Whether the form holds edits that a save would write. */\n dirty: boolean\n /** Whether any staged draft is invalid, which blocks the save. */\n invalid: boolean\n /** Whether a save is crossing the wire. */\n saving: boolean\n /** Whether the last save did not land as staged; cleared by the next edit or save. */\n failed: boolean\n}\n\n/** The write actions the card's slot entry injects. */\nexport interface CardActions {\n /** Stage draft text for one field. */\n edit: (field: string, text: string) => void\n /** Stage a clear, so saving lets the field re-inherit the composition layer. */\n resetField: (field: string) => void\n /** Write every staged edit, then re-seed from what the Host accepted. */\n save: () => void\n /** Drop every staged edit. */\n discard: () => void\n}\n\n/** One field's staged edit. */\ninterface StagedEdit {\n /** Draft text the control renders. */\n text: string\n /** True when this edit clears the field whatever text it shows. */\n clear: boolean\n}\n\n/** One staged edit resolved into the write a save performs. */\ninterface PlannedWrite {\n /** Field this entry writes. */\n field: string\n /** Perform the write and report whether the Host holds the staged value afterwards. */\n run: (() => Promise<boolean>) | undefined\n}\n\n/** A free-text field. An empty draft clears the field. */\nexport function textField(field: string): FieldSpec {\n return {\n field,\n format: value => typeof value === 'string' ? value : '',\n parse: (text) => {\n const trimmed = text.trim()\n return trimmed === '' ? { kind: 'clear' } : { kind: 'set', value: trimmed }\n },\n }\n}\n\n/** A newline/comma-separated model list, persisted as a normalized string array. */\nexport function stringListField(field: string): FieldSpec {\n return {\n field,\n format: value => Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string').join('\\n') : '',\n parse: (text) => {\n const values = [...new Set(text.split(/[\\n,]/).map(item => item.trim()).filter(Boolean))]\n return values.length === 0 ? { kind: 'clear' } : { kind: 'set', value: values }\n },\n }\n}\n\n/** A boolean field, edited through true/false draft text. */\nexport function booleanField(field: string): FieldSpec {\n return {\n field,\n format: value => typeof value === 'boolean' ? String(value) : '',\n parse: (text) => {\n if (text === 'true') return { kind: 'set', value: true }\n if (text === 'false') return { kind: 'set', value: false }\n return undefined\n },\n }\n}\n\n/**\n * A secret field (role('secret') in the namespace schema). The stored value is\n * never rendered or returned by the redacted wire view, so:\n * - an empty draft means \"no change\" (typing nothing must never clear an\n * invisible stored key); the dedicated clear action stages an explicit clear;\n * - a write's outcome is judged by the namespace's secrets sidecar through\n * the {@link CardForm} `secretSettled` hook, never by the user layer.\n */\nexport function secretField(field: string): FieldSpec {\n return {\n field,\n secret: true,\n format: () => '',\n parse: (text) => {\n const trimmed = text.trim()\n if (trimmed === '') return undefined\n return { kind: 'set', value: trimmed }\n },\n }\n}\n\n/**\n * Stages one card's edits over one settings scope and writes them on save.\n *\n * The Host is the only authority on whether a value was accepted — its\n * validators own the constraints no schema can express — so the outcome is\n * read back from the section rather than predicted here. A save that did not\n * land keeps its drafts, so the user can correct them instead of retyping.\n */\nexport class CardForm<T> {\n private readonly specs: Map<string, FieldSpec>\n private readonly staged = new Map<string, StagedEdit>()\n private readonly listeners = new Set<() => void>()\n private saving = false\n private failed = false\n\n /**\n * @param scope - the bound settings scope for this card's namespace.\n * @param specs - the fields this card edits.\n * @param options.secretSettled - for secret fields, whether the namespace\n * currently holds a stored secret (the redacted view never round-trips the\n * value, so a write's outcome is read from the secrets sidecar instead).\n */\n constructor(\n private readonly scope: SettingsScope<T>,\n specs: FieldSpec[],\n private readonly options: { secretSettled?: (field: string) => boolean } = {},\n ) {\n this.specs = new Map(specs.map(spec => [spec.field, spec]))\n scope.subscribe(() => { this.publish() })\n }\n\n /** Publish a projection of this form, rebuilt whenever the scope or a draft changes. */\n bind<S>(project: () => S): SnapshotStore<S> {\n const store = createSnapshotStore(project())\n this.listeners.add(() => { store.set(project()) })\n return store\n }\n\n /** Read the card-level state: what the Host serves, and what a save would do. */\n shell(): CardShell {\n const snapshot = this.scope.getSnapshot()\n const plan = this.plan()\n return {\n available: snapshot.status !== 'loading',\n exposed: snapshot.status === 'ready',\n writable: snapshot.writable,\n dirty: plan.length > 0,\n invalid: plan.some(item => item.run === undefined),\n saving: this.saving,\n failed: this.failed,\n }\n }\n\n /** Read one field's state from the effective section and its staged draft. */\n field(field: string): FieldState {\n const spec = this.specOf(field)\n const staged = this.staged.get(field)\n if (staged === undefined) {\n return { text: spec.format(this.sectionValue(field)), overridden: this.stored(field), invalid: false }\n }\n const write = staged.clear ? { kind: 'clear' as const } : spec.parse(staged.text)\n return {\n text: staged.text,\n overridden: write?.kind === 'set',\n // A secret field's empty draft is \"no change\" (see secretField), never\n // an invalid state — the stored value is invisible, so the user cannot\n // be expected to type over it.\n invalid: write === undefined && !(spec.secret === true && staged.text.trim() === ''),\n }\n }\n\n /** The actions the card's slot registration injects. */\n actions(): CardActions {\n return {\n edit: (field, text) => { this.stage(field, { text, clear: false }) },\n resetField: (field) => {\n this.stage(field, { text: this.specOf(field).format(this.baseValue(field)), clear: true })\n },\n save: () => { void this.save() },\n discard: () => {\n if (this.staged.size === 0 && !this.failed) return\n this.staged.clear()\n this.failed = false\n this.publish()\n },\n }\n }\n\n /**\n * Write every staged edit, then re-seed from what the Host accepted.\n * @returns settlement after every write and the read-back.\n */\n async save(): Promise<void> {\n const plan = this.plan()\n const writes = plan.flatMap(item => item.run === undefined ? [] : [item.run])\n if (plan.length === 0 || this.saving || writes.length !== plan.length) return\n this.saving = true\n this.failed = false\n this.publish()\n let landed = true\n for (const write of writes) {\n landed = await write() && landed\n }\n if (landed) this.staged.clear()\n this.saving = false\n this.failed = !landed\n this.publish()\n }\n\n /**\n * Every staged edit a save would write. An entry whose draft is not a value\n * its field accepts carries no write: the form is still dirty, and the save\n * refuses rather than dropping the edit. A staged edit that matches the\n * effective section is not a write at all.\n */\n private plan(): PlannedWrite[] {\n const plan: PlannedWrite[] = []\n for (const [field, staged] of this.staged) {\n const spec = this.specOf(field)\n if (staged.clear) {\n const present = spec.secret === true\n ? (this.options.secretSettled?.(field) ?? false)\n : this.stored(field)\n if (present) plan.push({ field, run: () => this.clear(field) })\n continue\n }\n if (staged.text === spec.format(this.sectionValue(field))) continue\n const write = spec.parse(staged.text)\n if (write === undefined) plan.push({ field, run: undefined })\n else if (write.kind === 'clear') plan.push({ field, run: () => this.clear(field) })\n else plan.push({ field, run: () => this.store(field, write.value) })\n }\n return plan\n }\n\n private async clear(field: string): Promise<boolean> {\n await this.scope.unset(field)\n const spec = this.specOf(field)\n if (spec.secret === true) return !(this.options.secretSettled?.(field) ?? false)\n return !this.stored(field)\n }\n\n private async store(field: string, value: unknown): Promise<boolean> {\n await this.scope.set(field, value)\n const spec = this.specOf(field)\n if (spec.secret === true) return this.options.secretSettled?.(field) ?? true\n return this.userLayer()?.[field] === value\n }\n\n private stage(field: string, edit: StagedEdit): void {\n this.staged.set(field, edit)\n this.failed = false\n this.publish()\n }\n\n private specOf(field: string): FieldSpec {\n const spec = this.specs.get(field)\n if (spec === undefined) throw new Error(`settings card has no field ${field}`)\n return spec\n }\n\n private snapshotOf(): SettingsScopeSnapshot<T> {\n return this.scope.getSnapshot()\n }\n\n private sectionValue(field: string): unknown {\n return (this.snapshotOf().value as Record<string, unknown> | undefined)?.[field]\n }\n\n private baseValue(field: string): unknown {\n return (this.snapshotOf().base as Record<string, unknown> | undefined)?.[field]\n }\n\n private userLayer(): Record<string, unknown> | undefined {\n return this.snapshotOf().user as Record<string, unknown> | undefined\n }\n\n private stored(field: string): boolean {\n const user = this.userLayer()\n return user !== undefined && Object.hasOwn(user, field)\n }\n\n private publish(): void {\n for (const listener of [...this.listeners]) listener()\n }\n}\n","/**\n * The dsh-imagegen settings card: api_url, api_key (secret, display-only\n * \"set\" state), and the plugin switches. Registers into the official\n * `settings.plugin.item` slot (the Settings → Plugins → Configurable tab),\n * independent of the dsh-web-ui family group, bound to the plugin's own\n * bridge settings scope.\n */\n\nimport { useState } from 'react'\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { createSnapshotStore, type SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'\nimport { CardForm, booleanField, secretField, stringListField, textField, type CardActions, type CardShell, type FieldState as CardFieldState } from './settings-form.ts'\nimport type { ImageGenScope } from './settings-scope.ts'\nimport { IMAGE_MODEL_API, PROMPT_ENHANCE_API } from '../protocol.ts'\nimport css from './settings-card.module.css'\n\n/** The fields this card edits (the namespace's full schema). */\nexport interface ImageGenSettings {\n enabled?: boolean\n announceToAgent?: boolean\n allowAgentImageGeneration?: boolean\n apiUrl?: string\n apiKey?: string\n imageModels?: string[]\n promptApiUrl?: string\n promptApiKey?: string\n promptModel?: string\n}\n\n/** What the card renders. */\nexport interface ImageGenSettingsCardState extends CardShell {\n /** Master switch. */\n enabled: CardFieldState\n /** System-prompt announcement flag. */\n announceToAgent: CardFieldState\n allowAgentImageGeneration: CardFieldState\n /** API base URL. */\n apiUrl: CardFieldState\n /** API key draft (the stored value is never rendered). */\n apiKey: CardFieldState\n imageModels: CardFieldState\n promptApiUrl: CardFieldState\n promptApiKey: CardFieldState\n promptModel: CardFieldState\n}\n\n/** The registration-side face the card's slot entry injects. */\nexport interface ImageGenSettingsCardFace extends CardActions {\n hooks: {\n /** Card snapshot bound by the renderer as useImageGenSettingsCard. */\n imageGenSettingsCard: SnapshotStore<ImageGenSettingsCardState>\n /** Whether a secret (apiKey) is currently stored. */\n imageGenKeySet: SnapshotStore<boolean>\n }\n}\n\n/** Bridges the imagegen scope onto the card's staged form. */\nexport class ImageGenSettingsCardController {\n private readonly form: CardForm<ImageGenSettings>\n\n /** @param scope - the bound bridge scope for the dsh-imagegen namespace. */\n constructor(private readonly scope: ImageGenScope) {\n this.form = new CardForm(scope, [\n booleanField('enabled'),\n booleanField('announceToAgent'),\n booleanField('allowAgentImageGeneration'),\n textField('apiUrl'),\n secretField('apiKey'),\n stringListField('imageModels'),\n textField('promptApiUrl'),\n secretField('promptApiKey'),\n textField('promptModel'),\n ], {\n // The redacted wire view never returns the key; a save's outcome is\n // judged by the namespace's secrets sidecar instead.\n secretSettled: () => this.scope.getKeySetSnapshot(),\n })\n }\n\n private projection(): ImageGenSettingsCardState {\n return {\n ...this.form.shell(),\n enabled: this.form.field('enabled'),\n announceToAgent: this.form.field('announceToAgent'),\n allowAgentImageGeneration: this.form.field('allowAgentImageGeneration'),\n apiUrl: this.form.field('apiUrl'),\n apiKey: this.form.field('apiKey'),\n imageModels: this.form.field('imageModels'),\n promptApiUrl: this.form.field('promptApiUrl'),\n promptApiKey: this.form.field('promptApiKey'),\n promptModel: this.form.field('promptModel'),\n }\n }\n\n /**\n * Build the face the card's slot registration injects.\n * @returns the card's snapshot, the key-set flag, and the form actions.\n */\n inject(): ImageGenSettingsCardFace {\n const cardStore = this.form.bind(() => this.projection())\n const keySetStore = createSnapshotStore(this.scope.getKeySetSnapshot())\n this.scope.subscribeKeySet(() => { keySetStore.set(this.scope.getKeySetSnapshot()) })\n return {\n hooks: {\n imageGenSettingsCard: cardStore,\n imageGenKeySet: keySetStore,\n },\n ...this.form.actions(),\n }\n }\n}\n\n/** Props the renderer binds for this card. */\nexport type ImageGenSettingsCardProps =\n PropsRuntime<'settings.plugin.item'>\n & PropsLocale<'dsh-imagegen'>\n & InjectFace<ImageGenSettingsCardFace>\n\n/**\n * Render the card.\n * @param props - locale copy, the card snapshot, and the form actions.\n * @returns the card, or nothing while the namespace is still loading.\n */\nexport function ImageGenSettingsCard(props: ImageGenSettingsCardProps) {\n const { t } = props\n const state = props.useImageGenSettingsCard(snapshot => snapshot)\n const keySet = props.useImageGenKeySet(snapshot => snapshot)\n const [open, setOpen] = useState(false)\n const [promptModels, setPromptModels] = useState<string[]>([])\n const [loadingPromptModels, setLoadingPromptModels] = useState(false)\n const [promptModelsError, setPromptModelsError] = useState<string | null>(null)\n const [imageModelCandidates, setImageModelCandidates] = useState<string[]>([])\n const [loadingImageModels, setLoadingImageModels] = useState(false)\n const [imageModelsError, setImageModelsError] = useState<string | null>(null)\n const [manualModelsOpen, setManualModelsOpen] = useState(false)\n const [manualModel, setManualModel] = useState('')\n const [enhancementOpen, setEnhancementOpen] = useState(false)\n const [manualPromptModelOpen, setManualPromptModelOpen] = useState(false)\n const [manualPromptModel, setManualPromptModel] = useState('')\n const [promptApiOpen, setPromptApiOpen] = useState(false)\n const [moreOpen, setMoreOpen] = useState(false)\n if (!state.available) return null\n const title = t('settings.title')\n const blocked = !state.dirty || state.invalid || state.saving\n const disabled = !state.writable\n const fieldProps = {\n overriddenLabel: t('settings.overridden'),\n resetLabel: t('settings.reset'),\n invalidLabel: t('settings.invalidNumber'),\n disabled,\n }\n if (!state.exposed) {\n return (\n <li className={css.card}>\n <button\n type=\"button\"\n className={css.header}\n aria-expanded={open}\n aria-label={`${t(open ? 'settings.collapse' : 'settings.expand')}: ${title}`}\n onClick={() => { setOpen(!open) }}\n >\n <span className={css.headText}>\n <span className={css.name}>{title}</span>\n <span className={css.description}>{t('settings.description')}</span>\n </span>\n <span className={open ? css.chevronOpen : css.chevron}>▾</span>\n </button>\n {open\n ? (\n <div className={css.body}>\n <p className={css.notExposed} role=\"status\">{t('settings.notExposed')}</p>\n </div>\n )\n : null}\n </li>\n )\n }\n return (\n <li className={css.card}>\n <button\n type=\"button\"\n className={css.header}\n aria-expanded={open}\n aria-label={`${t(open ? 'settings.collapse' : 'settings.expand')}: ${title}`}\n onClick={() => { setOpen(!open) }}\n >\n <span className={css.headText}>\n <span className={css.name}>{title}</span>\n <span className={css.description}>{t('settings.description')}</span>\n </span>\n {state.dirty ? <span className={css.pending}>{t('settings.unsaved')}</span> : null}\n <span className={open ? css.chevronOpen : css.chevron}>▾</span>\n </button>\n {open\n ? (\n <div className={css.body}>\n {!state.writable ? <p className={css.readOnly} role=\"status\">{t('settings.readOnly')}</p> : null}\n <ValueField\n id=\"dsh-imagegen-settings-apiurl\"\n label={t('settings.apiUrl')}\n hint={t('settings.apiUrlHint')}\n placeholder=\"https://api.openai.com/v1\"\n {...fieldProps}\n {...state.apiUrl}\n onEdit={(text) => { props.edit('apiUrl', text) }}\n onReset={() => { props.resetField('apiUrl') }}\n />\n <ValueField\n id=\"dsh-imagegen-settings-apikey\"\n label={t('settings.apiKey')}\n hint={keySet ? t('settings.apiKeySet') : t('settings.apiKeyHint')}\n placeholder=\"sk-…\"\n secret\n {...fieldProps}\n {...state.apiKey}\n overridden={false}\n onEdit={(text) => { props.edit('apiKey', text) }}\n onReset={() => { props.resetField('apiKey') }}\n clearLabel={t('settings.apiKeyClear')}\n onClear={() => { props.resetField('apiKey') }}\n canClear={keySet}\n />\n <div className={css.sectionDivider} />\n <section className={css.modelSection} aria-label={t('settings.imageModelsTitle')}>\n <div className={css.sectionHeader}>\n <div>\n <h3 className={css.sectionTitle}>{t('settings.imageModelsTitle')}</h3>\n <p className={css.sectionHint}>{t('settings.imageModelsHint')}</p>\n </div>\n <button\n type=\"button\"\n className={css.modelFetch}\n disabled={disabled || loadingImageModels}\n onClick={() => {\n setLoadingImageModels(true)\n setImageModelsError(null)\n void fetch(IMAGE_MODEL_API.models, { method: 'POST' })\n .then(async response => {\n const body = await response.json() as { ok?: boolean; models?: string[]; message?: string }\n if (!response.ok || body.ok !== true) throw new Error(body.message ?? `HTTP ${response.status}`)\n setImageModelCandidates(body.models ?? [])\n })\n .catch(error => { setImageModelsError(error instanceof Error ? error.message : String(error)) })\n .finally(() => { setLoadingImageModels(false) })\n }}\n >\n {loadingImageModels ? t('settings.imageModelsLoading') : t('settings.imageModelsFetch')}\n </button>\n </div>\n <div className={css.modelSummary}>\n {splitModels(state.imageModels.text).map(model => (\n <span key={model} className={css.modelChip}>\n <span>{model}</span>\n <button\n type=\"button\"\n disabled={disabled}\n aria-label={`${t('settings.removeModel')}: ${model}`}\n onClick={() => { props.edit('imageModels', splitModels(state.imageModels.text).filter(value => value !== model).join('\\n')) }}\n >\n ×\n </button>\n </span>\n ))}\n <button type=\"button\" className={css.addModel} disabled={disabled} onClick={() => { setManualModelsOpen(open => !open) }}>\n {manualModelsOpen ? t('settings.cancelAddModel') : t('settings.addModel')}\n </button>\n </div>\n {manualModelsOpen ? (\n <div className={css.manualModelRow}>\n <input\n className={css.input}\n value={manualModel}\n placeholder={t('settings.addModelPlaceholder')}\n disabled={disabled}\n onChange={event => { setManualModel(event.target.value) }}\n onKeyDown={event => {\n if (event.key !== 'Enter') return\n event.preventDefault()\n const next = manualModel.trim()\n if (next === '') return\n props.edit('imageModels', [...splitModels(state.imageModels.text), next].join('\\n'))\n setManualModel('')\n }}\n />\n <button\n type=\"button\"\n className={css.addModel}\n disabled={disabled || manualModel.trim() === ''}\n onClick={() => {\n props.edit('imageModels', [...splitModels(state.imageModels.text), manualModel.trim()].join('\\n'))\n setManualModel('')\n }}\n >\n {t('settings.addModelConfirm')}\n </button>\n </div>\n ) : null}\n {imageModelCandidates.length > 0 ? (\n <div className={css.modelCandidateList} role=\"group\" aria-label={t('settings.imageModelsCandidates')}>\n <span className={css.modelCandidateLabel}>{t('settings.imageModelsCandidates')}</span>\n {imageModelCandidates.map(candidate => {\n const selected = splitModels(state.imageModels.text).includes(candidate)\n return (\n <label key={candidate} className={css.modelCandidate} data-selected={selected ? '' : undefined}>\n <input\n type=\"checkbox\"\n checked={selected}\n disabled={disabled}\n onChange={() => {\n const selectedModels = splitModels(state.imageModels.text)\n const next = selected ? selectedModels.filter(model => model !== candidate) : [...selectedModels, candidate]\n props.edit('imageModels', next.join('\\n'))\n }}\n />\n <span>{candidate}</span>\n </label>\n )\n })}\n </div>\n ) : null}\n {imageModelsError !== null ? <p className={css.failed} role=\"status\">{imageModelsError}</p> : null}\n </section>\n <button\n type=\"button\"\n className={css.disclosure}\n aria-expanded={enhancementOpen}\n onClick={() => { setEnhancementOpen(open => !open) }}\n >\n <span>{t('settings.promptEnhanceTitle')}</span>\n <span>{t('settings.optional')}</span>\n <span aria-hidden=\"true\">{enhancementOpen ? '⌃' : '⌄'}</span>\n </button>\n {enhancementOpen ? <section className={css.optionalContent} aria-label={t('settings.promptEnhanceTitle')}>\n <p className={css.sectionHint}>{t('settings.promptEnhanceHint')}</p>\n <div className={css.sectionHeader}>\n <div>\n <h3 className={css.sectionTitle}>{t('settings.promptModel')}</h3>\n <p className={css.sectionHint}>{t('settings.promptModelDetectionHint')}</p>\n </div>\n <button\n type=\"button\"\n className={css.modelFetch}\n disabled={disabled || loadingPromptModels}\n onClick={() => {\n setLoadingPromptModels(true)\n setPromptModelsError(null)\n void fetch(PROMPT_ENHANCE_API.models, { method: 'POST' })\n .then(async response => {\n const body = await response.json() as { ok?: boolean; models?: string[]; message?: string }\n if (!response.ok || body.ok !== true) throw new Error(body.message ?? `HTTP ${response.status}`)\n setPromptModels(body.models ?? [])\n })\n .catch(error => { setPromptModelsError(error instanceof Error ? error.message : String(error)) })\n .finally(() => { setLoadingPromptModels(false) })\n }}\n >\n {loadingPromptModels ? t('settings.promptModelsLoading') : t('settings.promptModelsFetch')}\n </button>\n </div>\n <div className={css.modelSummary}>\n {state.promptModel.text.trim() !== '' ? (\n <span className={css.modelChip}>\n <span>{state.promptModel.text}</span>\n <button type=\"button\" disabled={disabled} aria-label={`${t('settings.removeModel')}: ${state.promptModel.text}`} onClick={() => { props.edit('promptModel', '') }}>×</button>\n </span>\n ) : null}\n <button type=\"button\" className={css.addModel} disabled={disabled} onClick={() => { setManualPromptModelOpen(open => !open) }}>\n {manualPromptModelOpen ? t('settings.cancelAddModel') : t('settings.addModel')}\n </button>\n </div>\n {manualPromptModelOpen ? (\n <div className={css.manualModelRow}>\n <input className={css.input} value={manualPromptModel} placeholder={t('settings.addPromptModelPlaceholder')} disabled={disabled} onChange={event => { setManualPromptModel(event.target.value) }} />\n <button type=\"button\" className={css.addModel} disabled={disabled || manualPromptModel.trim() === ''} onClick={() => { props.edit('promptModel', manualPromptModel); setManualPromptModel('') }}>\n {t('settings.addModelConfirm')}\n </button>\n </div>\n ) : null}\n {promptModels.length > 0 ? (\n <div className={css.modelCandidateList} role=\"radiogroup\" aria-label={t('settings.promptModelsCandidates')}>\n <span className={css.modelCandidateLabel}>{t('settings.promptModelsCandidates')}</span>\n {promptModels.map(candidate => (\n <button\n key={candidate}\n type=\"button\"\n role=\"radio\"\n className={css.modelCandidate}\n aria-checked={state.promptModel.text === candidate}\n data-selected={state.promptModel.text === candidate ? '' : undefined}\n disabled={disabled}\n onClick={() => { props.edit('promptModel', candidate) }}\n >\n {candidate}\n </button>\n ))}\n </div>\n ) : null}\n {promptModelsError !== null ? <p className={css.failed} role=\"status\">{promptModelsError}</p> : null}\n <button type=\"button\" className={css.inlineDisclosure} aria-expanded={promptApiOpen} onClick={() => { setPromptApiOpen(open => !open) }}>\n <span>{t('settings.promptApiAdvanced')}</span>\n <span aria-hidden=\"true\">{promptApiOpen ? '⌃' : '⌄'}</span>\n </button>\n {promptApiOpen ? <div className={css.optionalContent}>\n <ValueField\n id=\"dsh-imagegen-settings-prompt-apiurl\"\n label={t('settings.promptApiUrl')}\n hint={t('settings.promptApiUrlHint')}\n placeholder=\"https://api.openai.com/v1\"\n {...fieldProps}\n {...state.promptApiUrl}\n onEdit={(text) => { props.edit('promptApiUrl', text) }}\n onReset={() => { props.resetField('promptApiUrl') }}\n />\n <ValueField\n id=\"dsh-imagegen-settings-prompt-apikey\"\n label={t('settings.promptApiKey')}\n hint={t('settings.promptApiKeyHint')}\n placeholder=\"sk-…\"\n secret\n {...fieldProps}\n {...state.promptApiKey}\n overridden={false}\n onEdit={(text) => { props.edit('promptApiKey', text) }}\n onReset={() => { props.resetField('promptApiKey') }}\n />\n </div> : null}\n </section> : null}\n <button type=\"button\" className={css.disclosure} aria-expanded={moreOpen} onClick={() => { setMoreOpen(open => !open) }}>\n <span>{t('settings.moreOptions')}</span>\n <span aria-hidden=\"true\">{moreOpen ? '⌃' : '⌄'}</span>\n </button>\n {moreOpen ? <div className={css.optionalContent}>\n <BooleanField\n id=\"dsh-imagegen-settings-enabled\"\n label={t('settings.enabled')}\n hint={t('settings.enabledHint')}\n inheritLabel={t('settings.inherit')}\n onLabel={t('settings.on')}\n offLabel={t('settings.off')}\n {...fieldProps}\n {...state.enabled}\n onEdit={(text) => { props.edit('enabled', text) }}\n onReset={() => { props.resetField('enabled') }}\n />\n <BooleanField\n id=\"dsh-imagegen-settings-announce\"\n label={t('settings.announceToAgent')}\n hint={t('settings.announceToAgentHint')}\n inheritLabel={t('settings.inherit')}\n onLabel={t('settings.on')}\n offLabel={t('settings.off')}\n {...fieldProps}\n {...state.announceToAgent}\n onEdit={(text) => { props.edit('announceToAgent', text) }}\n onReset={() => { props.resetField('announceToAgent') }}\n />\n <BooleanField\n id=\"dsh-imagegen-settings-agent-generation\"\n label={t('settings.allowAgentImageGeneration')}\n hint={t('settings.allowAgentImageGenerationHint')}\n inheritLabel={t('settings.inherit')}\n onLabel={t('settings.on')}\n offLabel={t('settings.off')}\n {...fieldProps}\n {...state.allowAgentImageGeneration}\n onEdit={(text) => { props.edit('allowAgentImageGeneration', text) }}\n onReset={() => { props.resetField('allowAgentImageGeneration') }}\n />\n </div> : null}\n <div className={css.footer}>\n {state.failed ? <p className={css.failed} role=\"status\">{t('settings.saveFailed')}</p> : null}\n <button\n type=\"button\"\n className={css.discard}\n disabled={!state.dirty || state.saving}\n onClick={props.discard}\n >\n {t('settings.discard')}\n </button>\n <button\n type=\"button\"\n className={css.save}\n disabled={blocked}\n onClick={props.save}\n >\n {t(!state.saving ? 'settings.save' : 'settings.saving')}\n </button>\n </div>\n </div>\n )\n : null}\n </li>\n )\n}\n\n/** Props every field control needs regardless of its value type. */\ninterface FieldProps {\n /** Stable id associating the label with its control. */\n id: string\n /** Visible label. */\n label: string\n /** One-line explanation rendered under the control. */\n hint: string\n /** Draft text this control renders. */\n text: string\n /** True when saving would leave a user-layer entry for this field. */\n overridden: boolean\n /** True when the draft is not a value this field accepts. */\n invalid: boolean\n /** Copy for the overridden badge. */\n overriddenLabel: string\n /** Copy for the reset control. */\n resetLabel: string\n /** Copy shown in place of the hint while the draft is invalid. */\n invalidLabel: string\n /** Disables every control (read-only document, or an unavailable namespace). */\n disabled: boolean\n /** Stage draft text. */\n onEdit: (text: string) => void\n /** Stage a clear so the field re-inherits the composition layer. */\n onReset: () => void\n}\n\n/** A staged value field; `secret` renders a password control. */\nfunction ValueField(props: FieldProps & {\n /** Render a password control. */\n secret?: boolean\n /** Placeholder shown while the draft is empty. */\n placeholder?: string\n /** Label of the dedicated clear control (secret fields). */\n clearLabel?: string\n /** Stage a clear of the stored secret. */\n onClear?: () => void\n /** Whether a stored secret exists (enables the clear control). */\n canClear?: boolean\n /** Render a multiline input for newline-separated configuration values. */\n multiline?: boolean\n}) {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden\n ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button\n type=\"button\"\n className={css.reset}\n disabled={props.disabled}\n onClick={props.onReset}\n >\n {props.resetLabel}\n </button>\n </span>\n )\n : null}\n {props.secret === true && props.canClear === true\n ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={props.disabled}\n onClick={props.onClear}\n >\n {props.clearLabel ?? props.resetLabel}\n </button>\n )\n : null}\n </div>\n {props.multiline === true ? (\n <textarea\n id={props.id}\n className={props.invalid ? css.textareaInvalid : css.textarea}\n {...props.invalid ? { 'aria-invalid': true } : {}}\n value={props.text}\n placeholder={props.placeholder ?? ''}\n disabled={props.disabled}\n onChange={(event) => { props.onEdit(event.target.value) }}\n />\n ) : (\n <input\n id={props.id}\n className={props.invalid ? css.inputInvalid : css.input}\n type={props.secret === true ? 'password' : 'text'}\n autoComplete={props.secret === true ? 'off' : undefined}\n {...props.invalid ? { 'aria-invalid': true } : {}}\n value={props.text}\n placeholder={props.placeholder ?? ''}\n disabled={props.disabled}\n onChange={(event) => { props.onEdit(event.target.value) }}\n />\n )}\n <p className={props.invalid ? css.invalid : css.hint}>\n {props.invalid ? props.invalidLabel : props.hint}\n </p>\n </div>\n )\n}\n\nfunction splitModels(value: string): string[] {\n return [...new Set(value.split(/[\\n,]/).map(model => model.trim()).filter(Boolean))]\n}\n\n/** A staged boolean field: 继承 / 开 / 关. */\nfunction BooleanField(props: FieldProps & {\n /** Copy for the inherit option. */\n inheritLabel: string\n /** Copy for the on option. */\n onLabel: string\n /** Copy for the off option. */\n offLabel: string\n}) {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden\n ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button\n type=\"button\"\n className={css.reset}\n disabled={props.disabled}\n onClick={props.onReset}\n >\n {props.resetLabel}\n </button>\n </span>\n )\n : null}\n </div>\n <select\n id={props.id}\n className={css.select}\n value={props.text}\n disabled={props.disabled}\n onChange={(event) => { props.onEdit(event.target.value) }}\n >\n <option value=\"\">{props.inheritLabel}</option>\n <option value=\"true\">{props.onLabel}</option>\n <option value=\"false\">{props.offLabel}</option>\n </select>\n <p className={css.hint}>{props.hint}</p>\n </div>\n )\n}\n","/**\n * Browser-side settings scope for the dsh-imagegen namespace, served by the\n * plugin's own loopback bridge routes (/api/dsh-imagegen/settings). The\n * official rc.6 settings scope answers \"unavailable\" for every third-party\n * namespace (the host-apiproxy allowlist is hard-coded), so this package\n * re-serves its namespace through the host settings seam over a same-origin,\n * loopback-only HTTP pair — the same pattern the dsh-web-ui family bridge\n * uses, self-contained per plugin.\n */\n\nimport {\n createSnapshotStore,\n type SettingsScope,\n type SettingsScopeSnapshot,\n type SnapshotStore,\n} from '@deepseek-ai/dsh-client-runtime/client'\nimport { SETTINGS_API } from '../protocol.ts'\n\n/** The fields this plugin's settings card edits. */\nexport interface ImageGenConfig {\n enabled?: boolean\n announceToAgent?: boolean\n allowAgentImageGeneration?: boolean\n apiUrl?: string\n apiKey?: string\n imageModels?: string[]\n promptApiUrl?: string\n promptApiKey?: string\n promptModel?: string\n}\n\n/** Wire shape of one namespace view from the bridge. */\ninterface BridgeView {\n ns: string\n value: unknown\n base?: unknown\n user?: unknown\n revision: number\n secrets?: Array<{ path: string[]; set: boolean }>\n}\n\n/** The bridge response envelope ({ ok: true, value } | { ok: false, code, message }). */\ntype BridgeEnvelope =\n | { ok: true; value: { namespaces?: BridgeView[]; writable?: boolean } | BridgeView }\n | { ok: false; code: string; message: string }\n\n/** Settings wire face over the bridge routes (fetch-backed). */\nfunction createBridgeApi(fetchFn: typeof fetch): {\n settings: {\n describe(payload: Record<string, never>): Promise<{ result: BridgeEnvelope }>\n mutate(payload: { ns: string; ops: unknown[]; expectedRevision?: number }): Promise<{ result: BridgeEnvelope }>\n }\n} {\n const post = async (path: string, body: unknown): Promise<{ result: BridgeEnvelope }> => {\n try {\n const response = await fetchFn(path, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n })\n if (!response.ok) {\n return { result: { ok: false, code: 'internal', message: `bridge HTTP ${response.status}` } }\n }\n return { result: await response.json() as BridgeEnvelope }\n } catch {\n return { result: { ok: false, code: 'internal', message: 'settings bridge unreachable' } }\n }\n }\n return {\n settings: {\n describe: async payload => post(SETTINGS_API.describe, payload),\n mutate: async payload => post(SETTINGS_API.mutate, payload),\n },\n }\n}\n\n/**\n * A SettingsScope over the bridge face: serialized queue, revision-fenced\n * writes, recovery read after a refusal. Mirrors the official controller's\n * ordering but trusts the Host-seam value without re-running the wire-schema\n * validation — the seam already validated it.\n */\nclass BridgeScopeController<T> implements SettingsScope<T> {\n private readonly store: SnapshotStore<SettingsScopeSnapshot<T>>\n /** Whether the namespace currently holds a stored secret (e.g. apiKey). */\n private readonly keySet: SnapshotStore<boolean>\n /** Individual secret presence bits, keyed by the settings field name. */\n private readonly secretSets: SnapshotStore<Record<string, boolean>>\n private tail: Promise<void> = Promise.resolve()\n private disposed = false\n\n constructor(\n private readonly api: ReturnType<typeof createBridgeApi>['settings'],\n private readonly spec: { namespace: string },\n ) {\n this.store = createSnapshotStore<SettingsScopeSnapshot<T>>({\n status: 'loading',\n value: undefined,\n base: undefined,\n user: undefined,\n revision: undefined,\n writable: false,\n mode: 'host',\n })\n this.keySet = createSnapshotStore(false)\n this.secretSets = createSnapshotStore({})\n }\n\n getSnapshot(): SettingsScopeSnapshot<T> {\n return this.store.getSnapshot()\n }\n\n /** Whether a stored secret exists (from the redacted view's secrets list). */\n getKeySetSnapshot(): boolean {\n return this.keySet.getSnapshot()\n }\n\n /** Observe the secret-set flag. */\n subscribeKeySet(listener: () => void): () => void {\n return this.keySet.subscribe(listener)\n }\n\n /** Whether a specific secret field currently has a stored value. */\n getSecretSetSnapshot(field: string): boolean {\n return this.secretSets.getSnapshot()[field] === true\n }\n\n /** Observe changes to individual secret-field presence bits. */\n subscribeSecretSets(listener: () => void): () => void {\n return this.secretSets.subscribe(listener)\n }\n\n subscribe(listener: () => void): () => void {\n return this.store.subscribe(listener)\n }\n\n /** Queue a bridge refresh. */\n load(): Promise<void> {\n return this.enqueue(() => this.read())\n }\n\n set(field: string, value: unknown): Promise<void> {\n return this.enqueue(() => this.write({ op: 'set', path: [field], value }))\n }\n\n unset(field: string): Promise<void> {\n return this.enqueue(() => this.write({ op: 'unset', path: [field] }))\n }\n\n async dispose(): Promise<void> {\n this.disposed = true\n await this.tail\n }\n\n private enqueue(operation: () => Promise<void>): Promise<void> {\n if (this.disposed) return Promise.resolve()\n const task = this.tail.then(async () => {\n if (this.disposed) return\n await operation()\n })\n this.tail = task.catch(() => {})\n return task\n }\n\n private async read(): Promise<void> {\n let response\n try {\n response = await this.api.describe({})\n } catch {\n if (!this.disposed) this.store.update(draft => { draft.status = 'unavailable' })\n return\n }\n if (!response.result.ok || this.disposed) {\n if (!this.disposed) this.store.update(draft => { draft.status = 'unavailable' })\n return\n }\n const { namespaces, writable } = response.result.value as { namespaces?: BridgeView[]; writable?: boolean }\n const view = namespaces?.find(candidate => candidate.ns === this.spec.namespace)\n if (view === undefined) {\n this.store.update(draft => {\n draft.status = 'unavailable'\n draft.writable = writable === true\n })\n this.keySet.set(false)\n this.secretSets.set({})\n return\n }\n this.accept(view, writable)\n }\n\n private async write(op: { op: 'set' | 'unset'; path: string[]; value?: unknown }): Promise<void> {\n const revision = this.getSnapshot().revision\n let response\n try {\n response = await this.api.mutate({\n ns: this.spec.namespace,\n ops: [op],\n ...revision === undefined ? {} : { expectedRevision: revision },\n })\n } catch {\n await this.read()\n return\n }\n if (!response.result.ok || this.disposed) {\n await this.read()\n return\n }\n this.accept(response.result.value as BridgeView, undefined)\n }\n\n private accept(view: BridgeView, writable: boolean | undefined): void {\n this.store.update(draft => {\n draft.revision = view.revision\n draft.base = view.base\n draft.user = view.user\n if (writable !== undefined) draft.writable = writable\n draft.status = 'ready'\n // Trust the Host-seam value: the seam already validated it, and the\n // card binds without a narrowing decoder.\n draft.value = view.value as T\n })\n const secretSets = Object.fromEntries((view.secrets ?? []).map(secret => [secret.path.join('.'), secret.set]))\n this.keySet.set(Object.values(secretSets).some(Boolean))\n this.secretSets.set(secretSets)\n }\n}\n\n/** The bound scope plus the secret-set flag, as the card and panel consume it. */\nexport interface ImageGenScope extends SettingsScope<ImageGenConfig> {\n /** Queue a bridge refresh (the invalidation path re-reads the namespace). */\n load(): Promise<void>\n getKeySetSnapshot(): boolean\n subscribeKeySet(listener: () => void): () => void\n getSecretSetSnapshot(field: string): boolean\n subscribeSecretSets(listener: () => void): () => void\n}\n\n/**\n * Bind the dsh-imagegen settings scope over the bridge routes and start its\n * initial read (the caller mounts nothing until the scope settles).\n * @param fetchFn - the fetch implementation (the global fetch on loopback).\n * @returns the scope; unavailable when the bridge is unreachable.\n */\nexport function bindImageGenScope(fetchFn: typeof fetch = fetch): ImageGenScope {\n const controller = new BridgeScopeController<ImageGenConfig>(createBridgeApi(fetchFn).settings, {\n namespace: 'dsh-imagegen',\n })\n void controller.load()\n return controller\n}\n","/** Inline renderer for image-generation tool-result attachments. */\n\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'\nimport type { ClientContext, ISessions, SessionId, ToolCallBlock } from '@deepseek-ai/dsh-client-runtime/client'\nimport { useEffect, useMemo, useState } from 'react'\nimport css from './image-toolview.module.css'\n\n/** Owner props supplied by the host's keyed tool-call slot. */\nexport interface ImageToolViewOwnerProps {\n callId: string\n toolName: string\n block: ToolCallBlock\n cwd?: string\n home?: string\n openFile: (path: string) => void\n inspect?: () => void\n}\n\ninterface LoadedImage {\n ref: ImageAttachmentRef\n src: string\n}\n\ninterface ImageToolViewProps extends ImageToolViewOwnerProps {\n sessionId: SessionId\n}\n\nfunction isSettled(block: ToolCallBlock): block is Extract<ToolCallBlock, { kind: 'tool-result' }> {\n return 'kind' in block\n}\n\nfunction imageRefsOf(block: ToolCallBlock): ImageAttachmentRef[] {\n if (!isSettled(block)) return []\n return block.content.flatMap(content => content.type === 'image' ? [content.attachment] : [])\n}\n\nfunction textOf(block: ToolCallBlock): string {\n if (!isSettled(block)) return ''\n return block.content\n .filter(content => content.type === 'text')\n .map(content => content.text)\n .join('\\n')\n}\n\nfunction resultInfo(block: ToolCallBlock): { status: string; message: string } {\n if (!isSettled(block)) return { status: 'running', message: '正在生成图片…' }\n const text = textOf(block)\n try {\n const parsed = JSON.parse(text) as { status?: unknown; message?: unknown }\n return {\n status: typeof parsed.status === 'string' ? parsed.status : block.isError ? 'failed' : 'completed',\n message: typeof parsed.message === 'string' ? parsed.message : '',\n }\n } catch {\n return { status: block.isError ? 'failed' : 'completed', message: text }\n }\n}\n\nfunction statusLabel(status: string): string {\n if (status === 'running' || status === 'queued') return '生成中'\n if (status === 'failed') return '生成失败'\n if (status === 'cancelled') return '已取消'\n return '图片结果'\n}\n\nfunction useAttachmentImages(\n sessionId: SessionId,\n refs: ImageAttachmentRef[],\n load: (sessionId: SessionId, ref: ImageAttachmentRef) => Promise<string>,\n): { images: LoadedImage[]; error: string | null } {\n const key = useMemo(() => refs.map(ref => String(ref.attachmentId)).join('|'), [refs])\n const [images, setImages] = useState<LoadedImage[]>([])\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n let disposed = false\n const urls: string[] = []\n const revoke = (): void => {\n for (const url of urls) URL.revokeObjectURL(url)\n urls.length = 0\n }\n\n setImages([])\n setError(null)\n if (refs.length === 0) return () => { /* no attachments to clean up */ }\n\n void Promise.all(refs.map(async ref => {\n const src = await load(sessionId, ref)\n urls.push(src)\n return { ref, src }\n }))\n .then(next => {\n if (!disposed) setImages(next)\n })\n .catch(errorValue => {\n revoke()\n if (!disposed) setError(errorValue instanceof Error ? errorValue.message : String(errorValue))\n })\n\n return () => {\n disposed = true\n revoke()\n }\n }, [key, load, refs, sessionId])\n\n return { images, error }\n}\n\n/** Register the inline image result view for all image-generation result tools. */\nexport function registerImageToolviews(ctx: ClientContext): void {\n // Older client typings still expose the host-side SessionStore on the\n // generic Context property. The runtime service itself provides the newer\n // binding/session face, so resolve it through Cordis and narrow locally.\n const sessions = ctx.get('sessions') as unknown as ISessions | undefined\n const load = async (sessionId: SessionId, ref: ImageAttachmentRef): Promise<string> => {\n const session = sessions?.binding(sessionId)?.session\n if (session === undefined) throw new Error('当前会话不可用,无法读取图片附件。')\n const result = await session.readAttachment(ref.attachmentId)\n if (!result.ok) throw new Error(result.error.message)\n const blob = new Blob([new Uint8Array(result.value.data)], { type: result.value.attachment.mediaType })\n return URL.createObjectURL(blob)\n }\n\n const ImageToolView = (props: ImageToolViewProps): React.JSX.Element => {\n const refs = useMemo(() => imageRefsOf(props.block), [props.block])\n const { status, message } = resultInfo(props.block)\n const { images, error } = useAttachmentImages(props.sessionId, refs, load)\n\n return <section className={css.root} data-state={status} data-tool={props.toolName}>\n <header className={css.header}>\n <span className={css.icon} aria-hidden=\"true\">▧</span>\n <strong>{props.toolName}</strong>\n <span className={css.status}>{statusLabel(status)}</span>\n </header>\n {message !== '' && <p className={css.message}>{message}</p>}\n {images.length > 0 && <div className={css.images}>\n {images.map(image => <a\n className={css.imageLink}\n href={image.src}\n key={String(image.ref.attachmentId)}\n rel=\"noreferrer\"\n target=\"_blank\"\n title=\"打开原图\"\n >\n <img className={css.image} src={image.src} alt={image.ref.name ?? '生成图片'} />\n </a>)}\n </div>}\n {refs.length > 0 && images.length === 0 && error === null && <p className={css.loading}>正在加载图片…</p>}\n {error !== null && <p className={css.error}>{error}</p>}\n </section>\n }\n\n ctx.slots.inject('tool.call.toolview', function* () {\n for (const key of ['generate_image', 'edit_image', 'get_image_generation_task']) {\n yield ctx.slots.register({ name: 'tool.call.toolview', key }, ImageToolView)\n }\n })\n}\n","/**\r\n * Browser-half entry for the dsh-imagegen plugin — runs inside the dsh web\r\n * GUI.\r\n *\r\n * Registers the dsh-imagegen locale dictionaries, binds the plugin's own\r\n * settings scope (its bridge routes serve the namespace the official rc.6\r\n * allowlist would refuse), registers the settings card into the Web UI plugin\r\n * group slot, and mounts the two DOM surfaces: the sidebar entry row (toggles\r\n * the panel) and the generation studio in the center column. Failure policy:\r\n * DOM mounting problems are logged, never thrown — the web shell fails the\r\n * whole boot when a plugin apply throws, and an external plugin must not take\r\n * the GUI down.\r\n */\r\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\r\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'\r\n// Type-only: pulls the locale plugin's Context merge (ctx.locale).\r\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\r\n// Type-only: pulls the LocaleNamespaceMap merge table.\r\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\r\nimport { ImageGenApi } from './api.ts'\r\nimport { ImageGenController } from './controller.ts'\r\nimport { tt } from './helpers.ts'\r\nimport { en, zh, type ImageGenKey } from './locales.ts'\r\nimport { mountPanel } from './mount.tsx'\r\nimport { mountSidebarEntry } from './sidebar-entry.ts'\r\nimport { ImageGenSettingsCard, ImageGenSettingsCardController } from './SettingsCard.tsx'\nimport { bindImageGenScope, type ImageGenScope } from './settings-scope.ts'\nimport { registerImageToolviews, type ImageToolViewOwnerProps } from './image-toolview.tsx'\n\r\n/** Locale namespace this plugin owns. */\r\nconst NS = 'dsh-imagegen'\r\n\r\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\r\n interface LocaleNamespaceMap {\r\n /** dsh-imagegen surface copy. */\r\n 'dsh-imagegen': ImageGenKey\r\n }\r\n\r\n interface SlotMap {\n /**\r\n * The official plugin-configuration slot the Settings → Plugins →\r\n * Configurable tab declares and renders. This card registers there as its\r\n * own standalone card — independent of the dsh-web-ui family group — so\r\n * this plugin never reads as part of that family. Spelled here with the\r\n * same shape so this package can register without depending on the\r\n * sibling UI package.\r\n */\r\n 'settings.plugin.item': { kind: 'keyed'; scope: 'root'; owner: ImageGenPluginItemOwnerProps }\n /** Image-generation results render their durable image blocks inline. */\n 'tool.call.toolview': { kind: 'keyed'; scope: 'session'; owner: ImageToolViewOwnerProps }\n }\n}\n\r\n/** Owner share of a plugin card (the section supplies nothing). */\r\nexport interface ImageGenPluginItemOwnerProps {\r\n /** Marker field: card owner props are intentionally empty. */\r\n children?: never\r\n}\r\n\r\n/** Required services (fiber inject waiting — the runtime must be up first). */\r\nexport const inject = ['slots', 'locale', 'connection', 'sessions']\n\r\n/**\r\n * Mount the studio, its sidebar entry, and the settings card.\r\n * @param ctx - client root context (services: slots, locale, connection).\r\n */\r\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-imagegen: dictionaries')\n registerImageToolviews(ctx)\n\r\n const connection = ctx.get('connection') as ConnectionHandle | undefined\r\n const loopback = connection?.isLoopback === true\r\n // The bridge routes are loopback-fenced; remote browsers get an unavailable\r\n // scope (the card explains the gap) instead of failing fetches.\r\n const scope: ImageGenScope = bindImageGenScope(loopback\r\n ? (input, init) => fetch(input, init)\r\n : () => { throw new Error('settings bridge is loopback-only') })\r\n\r\n // Re-read the scope whenever the connection resets (same invalidation the\r\n // official settings binder wires).\r\n ctx.effect(() => {\r\n const disposers = [\r\n ctx.on('connection/reset', () => { void scope.load() }),\r\n ]\r\n return () => { for (const dispose of disposers) dispose() }\r\n }, 'dsh-imagegen: settings scope invalidation')\r\n\r\n // Plugin configuration card: one staged form over the `dsh-imagegen` scope,\r\n // registered into the official plugin-configuration slot (Settings →\r\n // Plugins → Configurable) as a standalone card.\r\n const settingsCard = new ImageGenSettingsCardController(scope)\r\n ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({\r\n name: 'settings.plugin.item',\r\n key: 'dsh-imagegen',\r\n locale: NS,\r\n inject: () => settingsCard.inject(),\r\n }, ImageGenSettingsCard))\r\n\r\n // The sidebar entry and studio mount once the settings scope settles; while\r\n // the scope is still loading, the composition default is unknown, so nothing\r\n // mounts yet. Only an unavailable scope falls back to the default (enabled).\r\n let uiDisposer: (() => void) | undefined\r\n const mountUi = (): void => {\r\n if (uiDisposer !== undefined) return\r\n const controller = new ImageGenController()\r\n const api = new ImageGenApi()\r\n const disposers: Array<() => void> = []\r\n try {\r\n disposers.push(mountSidebarEntry(controller, tt('entry.label'), tt('entry.tooltip')))\r\n disposers.push(mountPanel(controller, api, scope))\r\n } catch (error) {\r\n // DOM failures degrade the studio, never the GUI.\r\n console.warn('[dsh-imagegen] mount failed:', error)\r\n }\r\n uiDisposer = () => {\r\n for (const dispose of disposers.splice(0)) dispose()\r\n uiDisposer = undefined\r\n }\r\n }\r\n const syncEnabled = (): void => {\r\n const snapshot = scope.getSnapshot()\r\n const enabled = snapshot.status === 'ready'\r\n ? snapshot.value?.enabled ?? true\r\n : snapshot.status === 'unavailable'\r\n if (enabled) mountUi()\r\n else uiDisposer?.()\r\n }\r\n scope.subscribe(syncEnabled)\r\n syncEnabled()\r\n}\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["css","Button","css","Button","Pill","css","css","css","css"],"sources":["../src/protocol.ts","../src/client/api.ts","../src/client/controller.ts","../src/client/locales.ts","../src/client/helpers.ts","../src/client/TemplateLibrary.tsx","../src/client/settings-scope.ts","../src/image-models.ts","../src/client/ImageGenPanel.tsx","../src/client/mount.tsx","../src/client/sidebar-entry.ts","../src/client/settings-form.ts","../src/client/channels-form.ts","../src/model-catalog.ts","../src/client/SettingsCard.tsx","../src/client/image-toolview.tsx","../src/client/index.ts"],"sourcesContent":["/**\n * Wire contract shared by the host and client halves of dsh-imagegen: the\n * settings namespace, the route paths, and the generate payload/result shapes.\n * Pure types + constants 鈥?safe for the client bundle to inline.\n */\n\n/** Settings namespace this plugin owns (host settings seam + bridge). */\nexport const IMAGEGEN_SETTINGS_NAMESPACE = 'dsh-imagegen'\n\n/** Published package version shared by the host updater and the client UI. */\nexport const PLUGIN_VERSION = '1.3.0'\n\n/** Same-origin route family (loopback-only, mirroring the dsh-ssh fence). */\nexport const SETTINGS_API = {\n describe: '/api/dsh-imagegen/settings/describe',\n mutate: '/api/dsh-imagegen/settings/mutate',\n} as const\n\n/** The image-generation proxy route. */\nexport const GENERATE_API = '/api/dsh-imagegen/generate'\n\n/** Host-mediated OpenAI-compatible prompt enhancement endpoints. */\nexport const PROMPT_ENHANCE_API = {\n models: '/api/dsh-imagegen/prompt-enhance/models',\n enhance: '/api/dsh-imagegen/prompt-enhance',\n} as const\n\n/** Host-mediated candidate discovery for the configured image API. */\nexport const IMAGE_MODEL_API = {\n models: '/api/dsh-imagegen/image-models',\n} as const\n\n/** Host-served built-in provider catalog (channels the user can instantiate). */\nexport const PRESETS_API = '/api/dsh-imagegen/presets' as const\n\n/** Loopback-only image reader for Agent tool-result previews. */\nexport const AGENT_IMAGE_API = '/api/dsh-imagegen/agent-image' as const\n\n/**\n * Host-computed per-channel usage counters (generation-count badges in the\n * settings card): entries are tallied from the persisted history and gallery\n * by channel + model alias.\n */\nexport const USAGE_API = '/api/dsh-imagegen/usage' as const\n\n/** Host-resident generation queue endpoints. */\nexport const TASK_API = {\n submit: '/api/dsh-imagegen/tasks/submit',\n list: '/api/dsh-imagegen/tasks/list',\n cancel: '/api/dsh-imagegen/tasks/cancel',\n retry: '/api/dsh-imagegen/tasks/retry',\n} as const\n\n/** Host-mediated GitHub Release update routes. */\nexport const UPDATE_API = {\n check: '/api/dsh-imagegen/update/check',\n apply: '/api/dsh-imagegen/update/apply',\n} as const\n\n/**\n * Same-origin route family for the host-persisted generation history. Images\n * live as files under ~/.dsh/dsh-imagegen/images/ and are served back through\n * the `image` prefix route, so list responses carry metadata only (never\n * base64) and the browser loads thumbnails/previews lazily.\n */\nexport const HISTORY_API = {\n list: '/api/dsh-imagegen/history/list',\n append: '/api/dsh-imagegen/history/append',\n remove: '/api/dsh-imagegen/history/remove',\n clear: '/api/dsh-imagegen/history/clear',\n image: '/api/dsh-imagegen/history/image',\n} as const\n\n/**\n * Same-origin route family for the user-curated gallery (favorites). Entries\n * reuse the history wire shape and persist under ~/.dsh/dsh-imagegen/gallery/;\n * unlike history there is no size cap 鈥?the user adds images on purpose.\n */\nexport const GALLERY_API = {\n list: '/api/dsh-imagegen/gallery/list',\n append: '/api/dsh-imagegen/gallery/append',\n remove: '/api/dsh-imagegen/gallery/remove',\n clear: '/api/dsh-imagegen/gallery/clear',\n tags: '/api/dsh-imagegen/gallery/tags',\n image: '/api/dsh-imagegen/gallery/image',\n} as const\n\n/** Maximum number of history entries retained host-side (oldest evicted). */\nexport const HISTORY_MAX = 50\n\n/**\n * Same-origin route family for the bundled prompt-template library\n * (awesome-gpt-image-2 mirror). The case list ships inside the package and is\n * served by the host; reference images are proxied through the `image` prefix\n * route and cached on disk so repeated views never hit the network again.\n */\nexport const TEMPLATES_API = {\n list: '/api/dsh-imagegen/templates/list',\n refresh: '/api/dsh-imagegen/templates/refresh',\n image: '/api/dsh-imagegen/templates/image',\n} as const\n\n/** One prompt-library case as the browser consumes it. */\nexport interface TemplateCase {\n /** Upstream case number (stable across refreshes). */\n id: number\n /** Short case title. */\n title: string\n /** Full reusable prompt text. */\n prompt: string\n /** English category name (grouping key). */\n category: string\n /** Chinese category display name. */\n categoryZh: string\n /** Style tags. */\n styles: string[]\n /** Scene tags. */\n scenes: string[]\n /** Original author handle, e.g. @vista8. */\n sourceLabel: string\n /** Original author link. */\n sourceUrl: string\n /** awesome-gpt-image-2 repo anchor link. */\n githubUrl: string\n /** Reference-image file name served through the image route ('' when none). */\n image: string\n /** Whether the source gallery featured the case. */\n featured: boolean\n}\n\n/** Template-library list payload. */\nexport interface TemplateListResult {\n cases: TemplateCase[]\n total: number\n /** Where the served list came from. */\n origin: 'bundled' | 'refreshed'\n /** Upstream repository the library mirrors. */\n repository: string\n /** ISO time of the last successful refresh / bundle snapshot. */\n fetchedAt: string\n}\n\n/** Template-library refresh outcome. */\nexport interface TemplateRefreshResult {\n total: number\n fetchedAt: string\n}\n\n/** Generation modes. */\nexport type GenerateMode = 'text' | 'edit'\n\n/** A client → host generate request (what the panel collects). */\nexport interface GenerateRequest {\n /** text-to-image (images/generations) or image-to-image (images/edits). */\n mode: GenerateMode\n /**\n * User-facing model name (an alias from the channel's model catalog). The\n * host maps it onto the configured channel and fills `upstream` with the\n * real id before the engine sees it.\n */\n model: string\n /** The prompt. Upstream providers may impose their own length limits. */\n prompt: string\n /** Canvas size as an aspect ratio: 'auto' or e.g. '1:1' / '16:9' / '21:9'.\n * The host maps it onto each model's own vocabulary (aspect_ratio for Grok\n * and Nano Banana, resolution-tier size for Seedream, the closest pixel size for\n * OpenAI-compatible endpoints). */\n size: string\n /** Clarity tier: 'auto' | '1k' | '2k' | '4k'. The host maps it onto the\n * model's own vocabulary (resolution for Grok, image_size for Nano Banana,\n * and size for Seedream,\n * Nano Banana, quality for OpenAI). */\n quality: string\n /** Number of images, 1-4. */\n n: number\n /**\n * Passthrough detail parameter: '' (omit), 'standard', or 'high'. Some\n * gpt-image-2 gateways expose it; official OpenAI endpoints reject unknown\n * parameters, so the UI defaults to '' (omit).\n */\n detail: string\n /** Reference image as a data URL (edit mode only). */\n image?: string\n /** Original reference-image name, retained in the history entry. */\n refName?: string\n /** Channel this request targets (the host falls back to the default when\n * absent, and re-routes by model alias when the alias lives elsewhere). */\n channelId?: string\n /** Channel display name snapshot, kept on the history entry (host-filled). */\n channel?: string\n /** Upstream model id actually sent to the gateway (host-filled from the\n * alias mapping; defaults to `model` when absent). */\n upstream?: string\n}\n\n/** One generated image, normalized host-side to base64 so the browser never\n * has to fetch the upstream (no CORS, no key exposure). */\nexport interface GeneratedImage {\n /** Raw base64 payload (no data: prefix). */\n b64: string\n /** MIME type of the payload, e.g. image/png. */\n mime: string\n /** Upstream revised prompt, when provided. */\n revisedPrompt?: string\n}\n\n/** Successful generate outcome. */\nexport interface GenerateResult {\n images: GeneratedImage[]\n /** Updated host-persisted history, when returned by the generate route. */\n history?: HistoryEntry[]\n /** Persistence failure after images were successfully generated. */\n historyError?: string\n}\n\n/**\n * One model mapping in a channel's catalog: the display alias the user, the\n * panel, and the Agent see, and the upstream model id actually sent to the\n * gateway. The alias defaults to the upstream id but can be renamed freely.\n */\nexport interface ModelMapping {\n /** User-facing model name (defaults to the upstream id). */\n alias: string\n /** Upstream model id sent to the gateway. */\n id: string\n}\n\n/**\n * One configured image channel (provider). Secrets never live here — the API\n * key is stored at `channelSecrets.<channelId>` in the settings document so\n * whole-array writes can never clobber keys the user did not re-enter.\n */\nexport interface ChannelConfig {\n /** Stable channel id (the channelSecrets dict is keyed by it). */\n id: string\n /** Preset provider id this channel was created from ('' = custom). */\n preset: string\n /** Display name shown in the list, the panel, and Agent guidance. */\n name: string\n /** OpenAI-compatible base URL. */\n apiUrl: string\n /** The channel's model catalog (alias → upstream id). */\n models: ModelMapping[]\n}\n\n/** One built-in provider as the settings card consumes it. */\nexport interface PresetProviderView {\n id: string\n name: string\n apiUrl: string\n hint: string\n models: ModelMapping[]\n}\n\nexport type GenerationTaskStatus = 'queued' | 'running' | 'completed' | 'failed' | 'cancelled'\n\nexport interface GenerationTask {\n id: string\n request: GenerateRequest\n status: GenerationTaskStatus\n createdAt: number\n startedAt?: number\n finishedAt?: number\n result?: GenerateResult\n error?: string\n}\n\n/** GitHub Release update information shown by the client. */\nexport interface UpdateInfo {\n currentVersion: string\n latestVersion: string\n updateAvailable: boolean\n releaseUrl: string\n publishedAt?: string\n}\n\n/** One history image reference as the browser consumes it (a served URL). */\nexport interface HistoryImageRef {\n /** Same-origin URL: `${HISTORY_API.image}/<file>`. */\n url: string\n /** MIME type, e.g. image/png. */\n mime: string\n /** Upstream revised prompt, when provided. */\n revisedPrompt?: string\n}\n\n/** A saved generation as the browser consumes it (metadata + served images). */\nexport interface HistoryEntry {\n id: string\n createdAt: number\n mode: GenerateMode\n model: string\n prompt: string\n size: string\n quality: string\n detail: string\n n: number\n images: HistoryImageRef[]\n /** Reference-image filename (edit mode), kept for display only. */\n refName?: string\n /** User-managed gallery labels (unused by history entries). */\n tags?: string[]\n /** Channel id snapshot (usage counters key by it for new entries). */\n channelId?: string\n /** Channel display name snapshot (survives channel deletion). */\n channel?: string\n}\n\n/** A history entry the client submits for persistence (images still carry base64). */\nexport interface HistoryEntryInput {\n id: string\n createdAt: number\n mode: GenerateMode\n model: string\n prompt: string\n size: string\n quality: string\n detail: string\n n: number\n images: GeneratedImage[]\n refName?: string\n /** Channel id snapshot, tallied by the usage endpoint. */\n channelId?: string\n /** Channel display name snapshot (survives channel deletion). */\n channel?: string\n}\n","/**\n * Browser-side API client for the /api/dsh-imagegen route family. The only\n * data access path the panel uses — plain fetch, same origin.\n */\n\nimport { GALLERY_API, GENERATE_API, HISTORY_API, PROMPT_ENHANCE_API, TASK_API, TEMPLATES_API, UPDATE_API, type GenerateRequest, type GenerateResult, type GenerationTask, type HistoryEntry, type HistoryEntryInput, type TemplateListResult, type TemplateRefreshResult, type UpdateInfo } from '../protocol.ts'\n\n/** Error carrying the route's JSON error message. */\nexport class ImageGenApiError extends Error {\n /** Stable wire code from the host. */\n readonly code: string\n\n constructor(message: string, code = 'generate-failed') {\n super(message)\n this.name = 'ImageGenApiError'\n this.code = code\n }\n}\n\n/** Parse the { ok, ... } envelope or throw an ImageGenApiError. */\nasync function readEnvelope<T>(response: Response): Promise<T> {\n let body: unknown\n try {\n body = await response.json()\n } catch {\n throw new ImageGenApiError(`HTTP ${response.status}: invalid JSON response`)\n }\n if (body === null || typeof body !== 'object') {\n throw new ImageGenApiError(`HTTP ${response.status}: malformed response`)\n }\n const record = body as { ok?: unknown; message?: unknown; code?: unknown }\n if (record.ok !== true) {\n throw new ImageGenApiError(\n typeof record.message === 'string' ? record.message : `HTTP ${response.status}`,\n typeof record.code === 'string' ? record.code : 'generate-failed',\n )\n }\n return body as T\n}\n\n/** The browser half's data entry point. */\nexport class ImageGenApi {\n /** Ask the host to check the latest stable GitHub Release. */\n async updateCheck(): Promise<UpdateInfo> {\n const response = await fetch(UPDATE_API.check, { method: 'POST' })\n const body = await readEnvelope<{ ok: true; update: UpdateInfo }>(response)\n return body.update\n }\n\n /** Ask the host to install a previously discovered Release. */\n async updateApply(version: string): Promise<{ updatedVersion: string; restartRequired: boolean }> {\n const response = await fetch(UPDATE_API.apply, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ version }),\n })\n const body = await readEnvelope<{ ok: true; updatedVersion: string; restartRequired: boolean }>(response)\n return { updatedVersion: body.updatedVersion, restartRequired: body.restartRequired }\n }\n\n /** Forward one generate request to the host proxy. */\n async generate(request: GenerateRequest): Promise<GenerateResult> {\n const response = await fetch(GENERATE_API, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(request),\n })\n const body = await readEnvelope<{ ok: true; images: GenerateResult['images']; history?: HistoryEntry[]; historyError?: string }>(response)\n return {\n images: body.images,\n ...body.history === undefined ? {} : { history: body.history },\n ...body.historyError === undefined ? {} : { historyError: body.historyError },\n }\n }\n\n /** Ask the configured chat model to expand a concise image prompt. */\n async enhancePrompt(prompt: string): Promise<string> {\n const response = await fetch(PROMPT_ENHANCE_API.enhance, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ prompt }),\n })\n const body = await readEnvelope<{ ok: true; prompt: string }>(response)\n return body.prompt\n }\n\n async taskSubmit(request: GenerateRequest): Promise<GenerationTask> {\n const response = await fetch(TASK_API.submit, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(request) })\n return (await readEnvelope<{ ok: true; task: GenerationTask }>(response)).task\n }\n\n async taskList(): Promise<GenerationTask[]> {\n const response = await fetch(TASK_API.list, { method: 'POST' })\n return (await readEnvelope<{ ok: true; tasks: GenerationTask[] }>(response)).tasks\n }\n\n async taskCancel(id: string): Promise<GenerationTask> {\n const response = await fetch(TASK_API.cancel, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ id }) })\n return (await readEnvelope<{ ok: true; task: GenerationTask }>(response)).task\n }\n\n async taskRetry(id: string): Promise<GenerationTask> {\n const response = await fetch(TASK_API.retry, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ id }) })\n return (await readEnvelope<{ ok: true; task: GenerationTask }>(response)).task\n }\n\n /** List the host-persisted history (newest first). */\n async historyList(): Promise<HistoryEntry[]> {\n const response = await fetch(HISTORY_API.list, { method: 'POST' })\n const body = await readEnvelope<{ ok: true; entries: HistoryEntry[] }>(response)\n return body.entries\n }\n\n /** Remove one history entry by id. */\n async historyRemove(id: string): Promise<HistoryEntry[]> {\n const response = await fetch(HISTORY_API.remove, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id }),\n })\n const body = await readEnvelope<{ ok: true; entries: HistoryEntry[] }>(response)\n return body.entries\n }\n\n /** Clear the entire history. */\n async historyClear(): Promise<HistoryEntry[]> {\n const response = await fetch(HISTORY_API.clear, { method: 'POST' })\n const body = await readEnvelope<{ ok: true; entries: HistoryEntry[] }>(response)\n return body.entries\n }\n\n /** List the host-persisted gallery (newest first). */\n async galleryList(): Promise<HistoryEntry[]> {\n const response = await fetch(GALLERY_API.list, { method: 'POST' })\n const body = await readEnvelope<{ ok: true; entries: HistoryEntry[] }>(response)\n return body.entries\n }\n\n /** Append one image to the gallery. The host assigns the id and skips the\n * append when a content-identical image is already in the gallery. */\n async galleryAppend(entry: HistoryEntryInput): Promise<{ entries: HistoryEntry[]; added: boolean }> {\n const response = await fetch(GALLERY_API.append, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ entry }),\n })\n const body = await readEnvelope<{ ok: true; entries: HistoryEntry[]; added: boolean }>(response)\n return { entries: body.entries, added: body.added }\n }\n\n /** Remove one gallery entry by id. */\n async galleryRemove(id: string): Promise<HistoryEntry[]> {\n const response = await fetch(GALLERY_API.remove, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id }),\n })\n const body = await readEnvelope<{ ok: true; entries: HistoryEntry[] }>(response)\n return body.entries\n }\n\n /** Clear the entire gallery. */\n async galleryClear(): Promise<HistoryEntry[]> {\n const response = await fetch(GALLERY_API.clear, { method: 'POST' })\n const body = await readEnvelope<{ ok: true; entries: HistoryEntry[] }>(response)\n return body.entries\n }\n\n async gallerySetTags(id: string, tags: string[]): Promise<HistoryEntry[]> {\n const response = await fetch(GALLERY_API.tags, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ id, tags }) })\n return (await readEnvelope<{ ok: true; entries: HistoryEntry[] }>(response)).entries\n }\n\n /** Fetch the prompt-template library (bundled snapshot or refreshed copy). */\n async templatesList(): Promise<TemplateListResult> {\n const response = await fetch(TEMPLATES_API.list, { method: 'POST' })\n const body = await readEnvelope<TemplateListResult & { ok: true }>(response)\n return {\n cases: body.cases,\n total: body.total,\n origin: body.origin,\n repository: body.repository,\n fetchedAt: body.fetchedAt,\n }\n }\n\n /** Re-download the template library from the upstream mirror (host-side). */\n async templatesRefresh(): Promise<TemplateRefreshResult> {\n const response = await fetch(TEMPLATES_API.refresh, { method: 'POST' })\n const body = await readEnvelope<TemplateRefreshResult & { ok: true }>(response)\n return { total: body.total, fetchedAt: body.fetchedAt }\n }\n}\n","/**\n * Image-gen panel controller: the single owner of the panel's open/closed\n * state. Framework-free so the DOM mounts and the React panel share one tiny\n * subscription surface. The state lives only for the browser session.\n */\n\n/** Immutable controller snapshot for UI subscriptions. */\nexport interface ImageGenControllerSnapshot {\n panelOpen: boolean\n}\n\n/** The panel state owner the sidebar entry toggles and the view renders from. */\nexport class ImageGenController {\n private panelOpen = false\n private listeners = new Set<() => void>()\n\n getSnapshot(): ImageGenControllerSnapshot {\n return { panelOpen: this.panelOpen }\n }\n\n subscribe(fn: () => void): () => void {\n this.listeners.add(fn)\n return () => { this.listeners.delete(fn) }\n }\n\n open(): void {\n if (this.panelOpen) return\n this.panelOpen = true\n this.notify()\n }\n\n close(): void {\n if (!this.panelOpen) return\n this.panelOpen = false\n this.notify()\n }\n\n toggle(): void {\n if (this.panelOpen) this.close()\n else this.open()\n }\n\n private notify(): void {\n for (const fn of [...this.listeners]) fn()\n }\n}\n","/**\n * dsh-imagegen surface copy: zh is the key source, en mirrors every key.\n */\n\nexport const zh = {\n 'entry.label': 'AI 生图',\n 'entry.tooltip': 'AI 生图面板(gpt-image-2 / grok-imagine-image / nanobanana / seedream 系列)',\n 'panel.title': 'AI 生图',\n 'panel.githubTip': '觉得好用或有建议?欢迎来 GitHub 提 issues、点个 star 支持一下!',\n // mode\n 'mode.text': '文生图',\n 'mode.edit': '图生图',\n // prompt\n 'prompt.placeholder': '描述你想要的画面,例如:一只戴着宇航员头盔的橘猫,在月球上举起望远镜,水彩风格,柔和光线…',\n 'prompt.required': '请输入提示词',\n 'prompt.count': '{count}',\n 'prompt.enhance': '增强',\n 'prompt.enhancing': '增强中…',\n 'prompt.enhanceHint': '使用已配置的对话模型扩写提示词',\n 'prompt.configTitle': '请先配置提示词增强模型',\n 'prompt.configHint': '已打开设置。进入「插件 → AI 生图」,填写或复用 API 地址和密钥,选择对话模型并保存。',\n 'tasks.title': '生成任务',\n 'tasks.queued': '排队中',\n 'tasks.running': '生成中',\n 'tasks.completed': '已完成',\n 'tasks.failed': '失败',\n 'tasks.cancelled': '已取消',\n 'tasks.cancel': '取消',\n 'tasks.retry': '重试',\n // parameters\n 'params.size': '尺寸',\n 'params.quality': '清晰度',\n 'params.count': '生成数量',\n 'params.detail': '细节',\n 'size.auto': '自动',\n 'size.square': '1:1 方图',\n 'size.portrait34': '3:4 标准竖图',\n 'size.landscape43': '4:3 标准横图',\n 'size.portrait916': '9:16 竖屏',\n 'size.portrait23': '2:3 竖图',\n 'size.landscape32': '3:2 横图',\n 'size.wide169': '16:9 宽屏',\n 'size.ultrawide21': '21:9 超宽屏',\n 'quality.auto': '自动',\n 'quality.1k': '1K',\n 'quality.2k': '2K',\n 'quality.4k': '4K',\n 'count.one': '1 张',\n 'count.two': '2 张',\n 'count.three': '3 张',\n 'count.four': '4 张',\n 'detail.auto': '自动',\n 'detail.standard': '标准',\n 'detail.high': '高清',\n 'detail.hint': '透传参数,部分 gpt-image-2 网关支持;官方接口请保持「自动」',\n // footer\n 'model.label': '模型',\n 'compare.enable': '多模型对比',\n 'compare.models': '参与对比的模型',\n 'compare.title': '多模型结果对比',\n 'compare.fullscreen': '全屏对比',\n 'compare.selectRequired': '请至少选择一个对比模型',\n 'generate': '开始生成',\n 'generating': '生成中…',\n // edit reference image\n 'edit.upload': '点击或拖拽上传参考图片',\n 'edit.uploadHint': 'PNG / JPG / WEBP,不超过 10MB',\n 'edit.change': '更换图片',\n 'edit.remove': '移除',\n 'edit.required': '请先上传参考图片',\n // canvas\n 'canvas.emptyTitle': '开始你的创作',\n 'canvas.emptyHint': '在左侧输入提示词并点击「开始生成」,结果将显示在这里',\n 'canvas.error': '生成失败:{error}',\n 'canvas.submitting': '正在加入生成队列…',\n 'canvas.queued': '已加入生成队列',\n 'canvas.queueHint': '当前有 {count} 个任务等待处理',\n 'canvas.generating': '正在生成图片…',\n 'canvas.elapsed': '已用时 {seconds}s',\n 'canvas.images': '本次生成 {count} 张',\n 'download': '下载',\n 'revisedPrompt': '优化提示词:{prompt}',\n // history\n 'history.title': '历史记录',\n 'history.empty': '暂无历史记录,生成图片后会保存在这里',\n 'history.clear': '清空',\n 'history.restore': '恢复',\n 'history.delete': '删除',\n 'history.images': '张',\n 'history.viewing': '历史 · {time}',\n 'history.search': '搜索提示词或模型…',\n 'history.model': '模型筛选',\n 'history.ratio': '比例筛选',\n 'history.allModels': '全部模型',\n 'history.allRatios': '全部比例',\n // gallery\n 'gallery.title': '画廊',\n 'gallery.categories': '分类',\n 'gallery.all': '全部作品',\n 'gallery.gpt': 'gpt-image-2',\n 'gallery.grok': 'grok-imagine-image',\n 'gallery.ratio': '画面比例',\n 'gallery.tags': '标签',\n 'gallery.filterHint': '按生成模式、模型和比例筛选画廊',\n 'gallery.count': '· 共 {count} 幅',\n 'gallery.viewMode': '视图模式',\n 'gallery.masonry': '瀑布流',\n 'gallery.grid': '整齐网格',\n 'gallery.sort': '排序',\n 'gallery.newest': '最新发布',\n 'gallery.oldest': '最早发布',\n 'gallery.untitled': '未命名作品',\n 'gallery.search': '搜索作品或模型…',\n 'gallery.tagsPlaceholder': '标签,用逗号分隔',\n 'gallery.tagsApply': '添加标签',\n 'gallery.editTags': '编辑标签',\n 'gallery.tagsEditShort': '编辑',\n 'gallery.tagsSave': '保存',\n 'gallery.tagsCancel': '取消',\n 'gallery.selected': '已选 {count} 项',\n 'gallery.selectionDone': '完成选择',\n 'gallery.selectionClear': '取消选择',\n 'gallery.downloadSelected': '下载所选',\n 'gallery.exportJson': '导出 JSON',\n 'gallery.select': '选择作品',\n 'gallery.add': '加入画廊',\n 'gallery.added': '已加入画廊',\n 'gallery.already': '已在画廊中',\n 'gallery.delete': '移出画廊',\n 'gallery.clear': '清空画廊',\n 'gallery.empty': '画廊还是空的,把喜欢的图片加入进来吧',\n 'gallery.viewing': '画廊 · {time}',\n // preview\n 'preview.title': '图片预览',\n 'preview.open': '点击预览',\n 'preview.close': '关闭',\n 'preview.prev': '上一张',\n 'preview.next': '下一张',\n 'preview.index': '{index} / {total}',\n 'preview.zoomControls': '图片缩放控制',\n 'preview.zoomIn': '放大',\n 'preview.zoomOut': '缩小',\n 'preview.zoomReset': '重置缩放',\n 'preview.zoomLevel': '{percent}%',\n 'preview.copyPrompt': '复制提示词',\n 'preview.copied': '已复制',\n 'preview.addToEdit': '添加到图生图',\n // config banner\n 'config.missing': '尚未配置 API:请前往「设置 → 插件 → 可配置」为 AI 生图填写 api_url 与 api_key。',\n 'config.generationTitle': '请先配置生图 API',\n 'config.generationHint': '已自动打开 DSH「设置 → 插件 → AI 生图」。填写生图 API 地址与 API 密钥,保存后即可开始生成。',\n 'config.enhancementTitle': '请先配置提示词增强模型',\n 'config.enhancementHint': '已自动打开 DSH「设置 → 插件 → AI 生图」。填写或复用对话 API 地址和密钥,选择对话模型并保存。',\n 'config.disabledTitle': 'AI 生图插件已停用',\n 'config.disabledHint': '已自动打开 DSH「设置 → 插件 → AI 生图」。开启「启用插件」后即可生成图片。',\n 'config.configured': '已连接 {url}',\n 'config.disabled': '插件已停用,请在设置中重新启用。',\n 'connection.connected': '已连接',\n 'connection.disconnected': '未连接',\n // plugin update\n 'update.available': '检测到新版本:{version}',\n 'update.install': '在线更新',\n 'update.installing': '更新中…',\n 'update.success': '已更新到 {version},请重启 DSH',\n 'update.failed': '更新失败,请重试',\n 'update.release': '查看 Release',\n // settings card\n 'settings.title': 'AI 生图(dsh-imagegen)',\n 'settings.description': '配置图像生成 API 地址与密钥',\n 'settings.currentVersion': '当前版本',\n 'settings.apiUrl': 'API 地址(api_url)',\n 'settings.apiUrlHint': 'OpenAI 兼容接口基址,如 https://api.openai.com/v1;将自动拼接 /images/generations 与 /images/edits',\n 'settings.apiKey': 'API 密钥(api_key)',\n 'settings.apiKeyHint': 'Bearer 密钥,明文存于本机设置文档;界面只显示是否已设置',\n 'settings.apiKeySet': '已保存密钥;输入新值可更换,点击「清除」可删除',\n 'settings.apiKeyClear': '清除',\n 'settings.imageModelsTitle': '生图模型',\n 'settings.imageModelsHint': '保存 API 地址和密钥后检测候选模型;请只选择实际支持生图的项。',\n 'settings.imageModels': '允许使用的生图模型',\n 'settings.imageModelsManualHint': '一行一个模型;API 未提供 /models 时可手动填写。面板和 Agent 只能使用此列表。',\n 'settings.imageModelsFetch': '检测可用模型',\n 'settings.imageModelsLoading': '检测中…',\n 'settings.imageModelsCandidates': '检测到的候选模型(勾选后保存)',\n 'settings.addModel': '+ 手动添加',\n 'settings.cancelAddModel': '收起添加',\n 'settings.addModelPlaceholder': '输入模型名称,例如 qwen-image',\n 'settings.addModelConfirm': '添加',\n 'settings.removeModel': '移除模型',\n 'settings.optional': '可选',\n 'settings.moreOptions': '更多设置',\n 'settings.promptEnhanceTitle': '提示词增强模型',\n 'settings.promptEnhanceHint': '用于将简短描述扩写为更完整的生图提示词;留空的地址和密钥会复用生图配置。',\n 'settings.promptApiUrl': '对话 API 地址(可选)',\n 'settings.promptApiUrlHint': 'OpenAI 兼容基址;留空则复用图像 API 地址。',\n 'settings.promptApiKey': '对话 API 密钥(可选)',\n 'settings.promptApiKeyHint': '留空则复用图像 API 密钥。',\n 'settings.promptModel': '对话模型',\n 'settings.promptModelHint': '选择或填写支持 /chat/completions 的模型。',\n 'settings.promptModelDetectionHint': '默认复用生图 API;检测后点选一个模型即可。',\n 'settings.promptModelsFetch': '获取可用模型',\n 'settings.promptModelsLoading': '正在获取…',\n 'settings.promptModelsSelect': '选择一个模型',\n 'settings.promptModelsCandidates': '检测到的候选对话模型',\n 'settings.addPromptModelPlaceholder': '输入对话模型名称,例如 gpt-4.1-mini',\n 'settings.promptApiAdvanced': '使用独立对话 API(可选)',\n 'settings.announceToAgent': '向 Agent 播报本插件',\n 'settings.announceToAgentHint': '开启后,本插件的存在与能力会写入每个 Agent 的系统提示词',\n 'settings.allowAgentImageGeneration': '允许 Agent 调用生图',\n 'settings.allowAgentImageGenerationHint': '默认开启。关闭后,Agent 无法提交、查询或取消生图任务;侧边栏工作台不受影响。',\n 'settings.enabled': '启用插件',\n 'settings.enabledHint': '关闭后生图面板不可用(设置卡片始终可用)',\n 'settings.save': '保存',\n 'settings.saving': '保存中…',\n 'settings.discard': '放弃修改',\n 'settings.unsaved': '有未保存的修改',\n 'settings.saveFailed': '保存失败,请重试',\n 'settings.readOnly': '当前设置文档为只读,无法保存。',\n 'settings.notExposed': '设置命名空间不可用:本部署未提供该插件的设置服务。',\n 'settings.expand': '展开',\n 'settings.collapse': '收起',\n 'settings.inherit': '继承',\n 'settings.on': '开',\n 'settings.off': '关',\n 'settings.overridden': '已覆盖',\n 'settings.reset': '重置',\n 'settings.invalidNumber': '请输入有效数字',\n // template library\n 'templates.open': '模板库',\n 'templates.title': '提示词模板库',\n 'templates.meta': '共 {count} 个模板 · {origin}',\n 'templates.origin.bundled': '内置快照',\n 'templates.origin.refreshed': '在线刷新',\n 'templates.search': '搜索模板标题或提示词…',\n 'templates.all': '全部',\n 'templates.close': '关闭',\n 'templates.back': '返回列表',\n 'templates.use': '使用此提示词',\n 'templates.copy': '复制提示词',\n 'templates.copied': '已复制',\n 'templates.refresh': '刷新模板库',\n 'templates.refreshing': '刷新中…',\n 'templates.refreshed': '已刷新,共 {count} 个模板',\n 'templates.refreshFailed': '刷新失败:{error}',\n 'templates.cacheAll': '缓存全部图片',\n 'templates.cacheAllHint': '通过本机代理把全部参考图缓存到本地磁盘,之后离线也能浏览',\n 'templates.caching': '缓存中 {done}/{total}…',\n 'templates.cached': '图片已全部缓存',\n 'templates.empty': '没有匹配的模板',\n 'templates.loading': '正在加载模板库…',\n 'templates.loadFailed': '模板库加载失败:{error}',\n 'templates.retry': '重试',\n 'templates.attribution': '模板与图片来自 awesome-gpt-image-2 项目,作者链接见各模板详情',\n 'templates.source': '来源:vibeui.top',\n 'templates.featured': '精选',\n // channel management\n 'channels.title': '渠道',\n 'channels.hint': '填写各渠道的 API 地址与密钥即可使用对应模型',\n 'channels.empty': '尚无渠道,点击下方按钮添加',\n 'channels.addProvider': '添加提供方',\n 'channels.addCustom': '添加自定义渠道',\n 'channels.untitled': '未命名渠道',\n 'channels.keySet': '密钥已设置',\n 'channels.keyMissing': '未设置密钥',\n 'channels.modelCount': '{n} 个模型',\n 'channels.noModels': '未配置模型',\n 'channels.defaultLabel': '默认',\n 'channels.statusReady': '可用',\n 'channels.statusIncomplete': '配置未完成',\n 'channels.edit': '编辑',\n 'channels.delete': '删除',\n 'channels.deleteConfirmTitle': '删除渠道「{name}」?该渠道的密钥将被移除;历史与画廊中的记录仍会保留。',\n 'channels.confirm': '确认删除',\n 'channels.cancel': '取消',\n 'channels.editorTitle': '渠道',\n 'channels.editorSaveNote': '改动将随卡片底部「保存」一起生效',\n 'channels.displayName': '显示名称',\n 'channels.apiUrl': 'API 地址',\n 'channels.apiKey': 'API 密钥',\n 'channels.keyReplaceHint': '已配置 — 输入新值可替换',\n 'channels.keyMissingHint': '填写密钥',\n 'channels.keyClear': '清除密钥',\n 'channels.modelCatalogTitle': '模型目录',\n 'channels.noModelsHint': '暂无模型:点击「检测」拉取候选,或手动添加;别名(显示名)默认等于上游模型 id,可自行修改。',\n 'channels.detect': '重新检测',\n 'channels.detecting': '检测中…',\n 'channels.detectSuccess': '连通 ✓ · {n} 个候选',\n 'channels.detectFailed': '检测失败:{error}',\n 'channels.detectOk': '已连接该 API',\n 'channels.modelAliasLabel': '显示名(别名)',\n 'channels.modelIdLabel': '上游模型 id',\n 'channels.generated': '已生成 {n} 次',\n 'channels.unknownProtocol': '未知协议,按通用 OpenAI 协议尝试',\n 'channels.removeModel': '移除模型',\n 'channels.manualAddPlaceholder': '输入模型 id,例如 qwen-image',\n 'channels.addModelConfirm': '添加',\n 'channels.copyFrom': '从其他渠道复制…',\n 'channels.copyApply': '复制',\n 'channels.candidatesTitle': '候选模型(点击加入)',\n 'channels.candidatesQuick': '只勾已收录协议',\n 'channels.deleteThisChannel': '删除此渠道',\n 'channels.setDefault': '设为默认渠道',\n 'channels.presetPickerTitle': '添加提供方',\n 'channels.presetPickerHint': '选择一个内置提供方,仅需填写 API 密钥',\n 'channels.presetModelsHint': '{n} 个预置模型',\n 'channels.presetCustomHint': '自行填写 API 地址、密钥与模型目录',\n 'channels.presetLoadFailed': '加载提供方失败:{error}',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n 'entry.label': 'AI Image',\n 'entry.tooltip': 'AI image generation studio (gpt-image-2 / grok-imagine-image / nanobanana / seedream family)',\n 'panel.title': 'AI Image',\n 'panel.githubTip': 'Like it or have suggestions? Head to GitHub to open issues and star us!',\n 'mode.text': 'Text to Image',\n 'mode.edit': 'Image to Image',\n 'prompt.placeholder': 'Describe the picture you want, e.g. an orange cat in an astronaut helmet raising a telescope on the moon, watercolor style, soft light…',\n 'prompt.required': 'Enter a prompt first',\n 'prompt.count': '{count}',\n 'prompt.enhance': 'Enhance',\n 'prompt.enhancing': 'Enhancing…',\n 'prompt.enhanceHint': 'Expand the prompt with the configured chat model',\n 'prompt.configTitle': 'Configure a prompt enhancement model first',\n 'prompt.configHint': 'Settings has opened. Go to Plugins → AI Image, configure or reuse an API URL and key, choose a chat model, then save.',\n 'tasks.title': 'Generation tasks',\n 'tasks.queued': 'Queued',\n 'tasks.running': 'Generating',\n 'tasks.completed': 'Completed',\n 'tasks.failed': 'Failed',\n 'tasks.cancelled': 'Cancelled',\n 'tasks.cancel': 'Cancel',\n 'tasks.retry': 'Retry',\n 'params.size': 'Size',\n 'params.quality': 'Quality',\n 'params.count': 'Count',\n 'params.detail': 'Detail',\n 'size.auto': 'Auto',\n 'size.square': '1:1 Square',\n 'size.portrait34': '3:4 Portrait',\n 'size.landscape43': '4:3 Landscape',\n 'size.portrait916': '9:16 Vertical',\n 'size.portrait23': '2:3 Portrait',\n 'size.landscape32': '3:2 Landscape',\n 'size.wide169': '16:9 Widescreen',\n 'size.ultrawide21': '21:9 Ultrawide',\n 'quality.auto': 'Auto',\n 'quality.1k': '1K',\n 'quality.2k': '2K',\n 'quality.4k': '4K',\n 'count.one': '1',\n 'count.two': '2',\n 'count.three': '3',\n 'count.four': '4',\n 'detail.auto': 'Auto',\n 'detail.standard': 'Standard',\n 'detail.high': 'High',\n 'detail.hint': 'Passthrough parameter supported by some gpt-image-2 gateways; keep \"Auto\" for official endpoints',\n 'model.label': 'Model',\n 'compare.enable': 'Multi-model comparison',\n 'compare.models': 'Models to compare',\n 'compare.title': 'Multi-model comparison',\n 'compare.fullscreen': 'Fullscreen comparison',\n 'compare.selectRequired': 'Select at least one model',\n 'generate': 'Generate',\n 'generating': 'Generating…',\n 'edit.upload': 'Click or drag to upload a reference image',\n 'edit.uploadHint': 'PNG / JPG / WEBP, up to 10MB',\n 'edit.change': 'Change image',\n 'edit.remove': 'Remove',\n 'edit.required': 'Upload a reference image first',\n 'canvas.emptyTitle': 'Start creating',\n 'canvas.emptyHint': 'Enter a prompt on the left and click \"Generate\"; results appear here',\n 'canvas.error': 'Generation failed: {error}',\n 'canvas.submitting': 'Adding to the generation queue…',\n 'canvas.queued': 'Added to the generation queue',\n 'canvas.queueHint': '{count} task(s) waiting or generating',\n 'canvas.generating': 'Generating images…',\n 'canvas.elapsed': 'Elapsed {seconds}s',\n 'canvas.images': '{count} image(s) generated',\n 'download': 'Download',\n 'revisedPrompt': 'Refined prompt: {prompt}',\n 'history.title': 'History',\n 'history.empty': 'No history yet — generations will be saved here',\n 'history.clear': 'Clear',\n 'history.restore': 'Restore',\n 'history.delete': 'Delete',\n 'history.images': 'images',\n 'history.viewing': 'History · {time}',\n 'history.search': 'Search prompt or model…',\n 'history.model': 'Model filter',\n 'history.ratio': 'Ratio filter',\n 'history.allModels': 'All models',\n 'history.allRatios': 'All ratios',\n 'gallery.title': 'Gallery',\n 'gallery.categories': 'Categories',\n 'gallery.all': 'All works',\n 'gallery.gpt': 'gpt-image-2',\n 'gallery.grok': 'grok-imagine-image',\n 'gallery.ratio': 'Aspect ratio',\n 'gallery.tags': 'Tags',\n 'gallery.filterHint': 'Filter by mode, model, and aspect ratio',\n 'gallery.count': '· {count} works',\n 'gallery.viewMode': 'View mode',\n 'gallery.masonry': 'Masonry',\n 'gallery.grid': 'Grid',\n 'gallery.sort': 'Sort',\n 'gallery.newest': 'Newest',\n 'gallery.oldest': 'Oldest',\n 'gallery.untitled': 'Untitled work',\n 'gallery.search': 'Search works or models…',\n 'gallery.tagsPlaceholder': 'Tags, comma separated',\n 'gallery.tagsApply': 'Add tags',\n 'gallery.editTags': 'Edit tags',\n 'gallery.tagsEditShort': 'Edit',\n 'gallery.tagsSave': 'Save',\n 'gallery.tagsCancel': 'Cancel',\n 'gallery.selected': '{count} selected',\n 'gallery.selectionDone': 'Done selecting',\n 'gallery.selectionClear': 'Clear selection',\n 'gallery.downloadSelected': 'Download selected',\n 'gallery.exportJson': 'Export JSON',\n 'gallery.select': 'Select work',\n 'gallery.add': 'Add to gallery',\n 'gallery.added': 'Added to gallery',\n 'gallery.already': 'Already in gallery',\n 'gallery.delete': 'Remove',\n 'gallery.clear': 'Clear gallery',\n 'gallery.empty': 'The gallery is empty — add images you like here',\n 'gallery.viewing': 'Gallery · {time}',\n 'preview.title': 'Image preview',\n 'preview.open': 'Click to preview',\n 'preview.close': 'Close',\n 'preview.prev': 'Previous',\n 'preview.next': 'Next',\n 'preview.index': '{index} / {total}',\n 'preview.zoomControls': 'Image zoom controls',\n 'preview.zoomIn': 'Zoom in',\n 'preview.zoomOut': 'Zoom out',\n 'preview.zoomReset': 'Reset zoom',\n 'preview.zoomLevel': '{percent}%',\n 'preview.copyPrompt': 'Copy prompt',\n 'preview.copied': 'Copied',\n 'preview.addToEdit': 'Add to image to image',\n 'config.missing': 'API not configured: open \"Settings → Plugins → Configurable\" and fill in api_url and api_key for AI Image.',\n 'config.generationTitle': 'Configure the image API first',\n 'config.generationHint': 'DSH Settings → Plugins → AI Image has opened. Enter the image API URL and API key, then save before generating.',\n 'config.enhancementTitle': 'Configure a prompt enhancement model first',\n 'config.enhancementHint': 'DSH Settings → Plugins → AI Image has opened. Configure or reuse a chat API URL and key, choose a chat model, then save.',\n 'config.disabledTitle': 'The AI Image plugin is disabled',\n 'config.disabledHint': 'DSH Settings → Plugins → AI Image has opened. Enable the plugin, then generate images.',\n 'config.configured': 'Connected to {url}',\n 'config.disabled': 'The plugin is disabled — re-enable it in Settings.',\n 'connection.connected': 'Connected',\n 'connection.disconnected': 'Disconnected',\n 'update.available': 'A new version is available: {version}',\n 'update.install': 'Update online',\n 'update.installing': 'Updating…',\n 'update.success': 'Updated to {version}; restart DSH to load it',\n 'update.failed': 'Update failed; please try again',\n 'update.release': 'View Release',\n 'settings.title': 'AI Image (dsh-imagegen)',\n 'settings.description': 'Configure the image generation API endpoint and key',\n 'settings.currentVersion': 'Current version',\n 'settings.apiUrl': 'API URL (api_url)',\n 'settings.apiUrlHint': 'OpenAI-compatible base URL, e.g. https://api.openai.com/v1; /images/generations and /images/edits are appended',\n 'settings.apiKey': 'API Key (api_key)',\n 'settings.apiKeyHint': 'Bearer key, stored in plaintext in the local settings document; the UI only shows whether it is set',\n 'settings.apiKeySet': 'A key is stored; type a new value to replace it, or click \"Clear\" to remove it',\n 'settings.apiKeyClear': 'Clear',\n 'settings.imageModelsTitle': 'Image generation models',\n 'settings.imageModelsHint': 'Save the API URL and key, then detect candidate models. Select only models that actually support image generation.',\n 'settings.imageModels': 'Allowed image models',\n 'settings.imageModelsManualHint': 'One model per line. Add models manually when the API does not provide /models. The panel and Agent can use only this list.',\n 'settings.imageModelsFetch': 'Detect available models',\n 'settings.imageModelsLoading': 'Detecting…',\n 'settings.imageModelsCandidates': 'Detected candidate models (select, then save)',\n 'settings.addModel': '+ Add manually',\n 'settings.cancelAddModel': 'Hide add',\n 'settings.addModelPlaceholder': 'Enter a model name, e.g. qwen-image',\n 'settings.addModelConfirm': 'Add',\n 'settings.removeModel': 'Remove model',\n 'settings.optional': 'Optional',\n 'settings.moreOptions': 'More settings',\n 'settings.promptEnhanceTitle': 'Prompt enhancement model',\n 'settings.promptEnhanceHint': 'Expands short requests into complete image prompts. Blank URL and key reuse the image API configuration.',\n 'settings.promptApiUrl': 'Chat API URL (optional)',\n 'settings.promptApiUrlHint': 'OpenAI-compatible base URL. Leave blank to reuse the image API URL.',\n 'settings.promptApiKey': 'Chat API key (optional)',\n 'settings.promptApiKeyHint': 'Leave blank to reuse the image API key.',\n 'settings.promptModel': 'Chat model',\n 'settings.promptModelHint': 'Select or enter a model supporting /chat/completions.',\n 'settings.promptModelDetectionHint': 'Uses the image API by default. Detect and select one model.',\n 'settings.promptModelsFetch': 'Fetch available models',\n 'settings.promptModelsLoading': 'Fetching…',\n 'settings.promptModelsSelect': 'Select a model',\n 'settings.promptModelsCandidates': 'Detected chat model candidates',\n 'settings.addPromptModelPlaceholder': 'Enter a chat model name, e.g. gpt-4.1-mini',\n 'settings.promptApiAdvanced': 'Use a separate chat API (optional)',\n 'settings.announceToAgent': 'Announce this plugin to agents',\n 'settings.announceToAgentHint': 'When on, the plugin presence and capabilities are written into every agent system prompt',\n 'settings.allowAgentImageGeneration': 'Allow agents to generate images',\n 'settings.allowAgentImageGenerationHint': 'On by default. When off, agents cannot submit, query, or cancel image tasks; the sidebar studio remains available.',\n 'settings.enabled': 'Enable plugin',\n 'settings.enabledHint': 'When off, the generation studio is unavailable (this card stays available)',\n 'settings.save': 'Save',\n 'settings.saving': 'Saving…',\n 'settings.discard': 'Discard',\n 'settings.unsaved': 'Unsaved changes',\n 'settings.saveFailed': 'Save failed, please retry',\n 'settings.readOnly': 'The settings document is read-only; saving is disabled.',\n 'settings.notExposed': 'Settings namespace unavailable: this deployment does not serve this plugin\\'s settings.',\n 'settings.expand': 'Expand',\n 'settings.collapse': 'Collapse',\n 'settings.inherit': 'Inherit',\n 'settings.on': 'On',\n 'settings.off': 'Off',\n 'settings.overridden': 'Overridden',\n 'settings.reset': 'Reset',\n 'settings.invalidNumber': 'Enter a valid number',\n // template library\n 'templates.open': 'Templates',\n 'templates.title': 'Prompt Template Library',\n 'templates.meta': '{count} templates · {origin}',\n 'templates.origin.bundled': 'bundled snapshot',\n 'templates.origin.refreshed': 'refreshed online',\n 'templates.search': 'Search template titles or prompts…',\n 'templates.all': 'All',\n 'templates.close': 'Close',\n 'templates.back': 'Back to list',\n 'templates.use': 'Use this prompt',\n 'templates.copy': 'Copy prompt',\n 'templates.copied': 'Copied',\n 'templates.refresh': 'Refresh library',\n 'templates.refreshing': 'Refreshing…',\n 'templates.refreshed': 'Refreshed — {count} templates',\n 'templates.refreshFailed': 'Refresh failed: {error}',\n 'templates.cacheAll': 'Cache all images',\n 'templates.cacheAllHint': 'Mirror every reference image to local disk through the host proxy, for offline browsing',\n 'templates.caching': 'Caching {done}/{total}…',\n 'templates.cached': 'All images cached',\n 'templates.empty': 'No matching templates',\n 'templates.loading': 'Loading the template library…',\n 'templates.loadFailed': 'Failed to load the library: {error}',\n 'templates.retry': 'Retry',\n 'templates.attribution': 'Templates and images come from the awesome-gpt-image-2 project; author links are on each template',\n 'templates.source': 'Source: vibeui.top',\n 'templates.featured': 'Featured',\n // channel management\n 'channels.title': 'Channels',\n 'channels.hint': 'Fill in each channel\\'s API URL and key to use its models',\n 'channels.empty': 'No channels yet — add one below',\n 'channels.addProvider': 'Add provider',\n 'channels.addCustom': 'Add custom channel',\n 'channels.untitled': 'Untitled channel',\n 'channels.keySet': 'Key set',\n 'channels.keyMissing': 'Key missing',\n 'channels.modelCount': '{n} model(s)',\n 'channels.noModels': 'No models',\n 'channels.defaultLabel': 'Default',\n 'channels.statusReady': 'Ready',\n 'channels.statusIncomplete': 'Config incomplete',\n 'channels.edit': 'Edit',\n 'channels.delete': 'Delete',\n 'channels.deleteConfirmTitle': 'Delete channel \"{name}\"? Its key will be removed; history and gallery records are kept.',\n 'channels.confirm': 'Delete',\n 'channels.cancel': 'Cancel',\n 'channels.editorTitle': 'Channel',\n 'channels.editorSaveNote': 'Changes take effect with the card\\'s \"Save\" button',\n 'channels.displayName': 'Display name',\n 'channels.apiUrl': 'API URL',\n 'channels.apiKey': 'API key',\n 'channels.keyReplaceHint': 'Configured — type a new value to replace it',\n 'channels.keyMissingHint': 'Enter a key',\n 'channels.keyClear': 'Clear key',\n 'channels.modelCatalogTitle': 'Model catalog',\n 'channels.noModelsHint': 'No models yet: run \"Detect\" to pull candidates, or add one manually; the alias (display name) defaults to the upstream model id and can be renamed.',\n 'channels.detect': 'Re-detect',\n 'channels.detecting': 'Detecting…',\n 'channels.detectSuccess': 'Connected ✓ · {n} candidates',\n 'channels.detectFailed': 'Detection failed: {error}',\n 'channels.detectOk': 'Connected to this API',\n 'channels.modelAliasLabel': 'Display name (alias)',\n 'channels.modelIdLabel': 'Upstream model id',\n 'channels.generated': 'Generated {n} time(s)',\n 'channels.unknownProtocol': 'Unknown protocol — best-effort OpenAI',\n 'channels.removeModel': 'Remove model',\n 'channels.manualAddPlaceholder': 'Enter a model id, e.g. qwen-image',\n 'channels.addModelConfirm': 'Add',\n 'channels.copyFrom': 'Copy from another channel…',\n 'channels.copyApply': 'Copy',\n 'channels.candidatesTitle': 'Candidates (click to add)',\n 'channels.candidatesQuick': 'Add only known protocols',\n 'channels.deleteThisChannel': 'Delete this channel',\n 'channels.setDefault': 'Set as default channel',\n 'channels.presetPickerTitle': 'Add provider',\n 'channels.presetPickerHint': 'Pick a built-in provider — only the API key is needed',\n 'channels.presetModelsHint': '{n} preset model(s)',\n 'channels.presetCustomHint': 'Configure the API URL, key, and model catalog yourself',\n 'channels.presetLoadFailed': 'Failed to load providers: {error}',\n}\n\n/** Locale key union. */\nexport type ImageGenKey = keyof typeof zh\n","/**\n * Shared panel helpers: the active-dictionary pick (document-language based,\n * dsh-ssh precedent) bound to the dsh-imagegen interpolator, plus a small\n * error-message extractor. All copy stays in the locale dictionaries.\n */\n\nimport { en, zh, type ImageGenKey } from './locales.ts'\n\n/** Template values accepted by the interpolator. */\nexport type TranslateValues = Record<string, string | number>\n\n/** Active dictionary, picked by the document language at call time. */\nexport function dictionary(): Record<string, string> {\n const lang = typeof document !== 'undefined' ? document.documentElement.lang : 'zh'\n return lang.toLowerCase().startsWith('en') ? { ...en } : { ...zh }\n}\n\n/** Translate a key with optional {name} template params (current language). */\nexport function tt(key: ImageGenKey, values?: TranslateValues): string {\n const text = dictionary()[key] ?? key\n if (values === undefined) return text\n let rendered = text\n for (const [name, value] of Object.entries(values)) {\n rendered = rendered.replaceAll(`{${name}}`, String(value))\n }\n return rendered\n}\n\n/** Human-readable error text from an unknown thrown value. */\nexport function errorMessage(error: unknown): string {\n if (error instanceof Error) return error.message\n return String(error)\n}\n","/**\n * Prompt-template library overlay: a searchable, category-filtered gallery of\n * the bundled awesome-gpt-image-2 cases. The case list is served by the host\n * (bundled snapshot, optionally refreshed online); reference images load\n * lazily through the host's caching proxy, so browsing progressively mirrors\n * the gallery onto the local disk. Picking a template hands its prompt back\n * to the studio form.\n */\n\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport { Button } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { ImageGenApi } from './api.ts'\nimport { errorMessage, tt } from './helpers.ts'\nimport { TEMPLATES_API, type TemplateCase, type TemplateListResult } from '../protocol.ts'\nimport css from './templates.module.css'\n\n/** Concurrent image downloads while caching the whole gallery offline. */\nconst CACHE_ALL_CONCURRENCY = 4\n\n/** Same-origin URL of one case's reference image (host caching proxy). */\nfunction imageUrlOf(item: TemplateCase): string {\n return `${TEMPLATES_API.image}/${encodeURIComponent(item.image)}`\n}\n\n/** A card thumbnail that falls back to a placeholder when the proxy 404s. */\nfunction TemplateThumb(props: { item: TemplateCase }) {\n const [failed, setFailed] = useState(false)\n if (props.item.image === '' || failed) {\n return (\n <span className={css.thumbPlaceholder} aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" width=\"26\" height=\"26\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"3\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><path d=\"M21 15l-5-5L5 21\"/></svg>\n </span>\n )\n }\n return (\n <img\n className={css.thumb}\n src={imageUrlOf(props.item)}\n alt={props.item.title}\n loading=\"lazy\"\n onError={() => { setFailed(true) }}\n />\n )\n}\n\n/** The template-library modal. Rendered through a portal above the studio. */\nexport function TemplateLibrary(props: {\n api: ImageGenApi\n /** Hand a picked prompt back to the studio form and close the library. */\n onUse: (prompt: string) => void\n onClose: () => void\n}) {\n const { api, onUse, onClose } = props\n const [list, setList] = useState<TemplateListResult | null>(null)\n const [loadError, setLoadError] = useState<string | null>(null)\n const [query, setQuery] = useState('')\n const [category, setCategory] = useState('')\n const [selected, setSelected] = useState<TemplateCase | null>(null)\n const [copied, setCopied] = useState(false)\n const [refreshing, setRefreshing] = useState(false)\n const [notice, setNotice] = useState<string | null>(null)\n const [cacheAll, setCacheAll] = useState<{ running: boolean; done: number; total: number }>({ running: false, done: 0, total: 0 })\n const searchRef = useRef<HTMLInputElement>(null)\n const load = (): void => {\n api.templatesList()\n .then(result => { setList(result); setLoadError(null) })\n .catch(caught => { setLoadError(errorMessage(caught)) })\n }\n\n // Load once on open; focus the search box for immediate typing.\n useEffect(() => {\n load()\n searchRef.current?.focus()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const categories = useMemo(() => {\n if (list === null) return [] as Array<{ key: string; label: string; count: number }>\n const counts = new Map<string, { label: string; count: number }>()\n for (const item of list.cases) {\n const entry = counts.get(item.category) ?? { label: item.categoryZh || item.category, count: 0 }\n entry.count += 1\n counts.set(item.category, entry)\n }\n return [...counts.entries()].map(([key, value]) => ({ key, label: value.label, count: value.count }))\n }, [list])\n\n const filtered = useMemo(() => {\n if (list === null) return [] as TemplateCase[]\n const needle = query.trim().toLowerCase()\n return list.cases.filter(item => {\n if (category !== '' && item.category !== category) return false\n if (needle === '') return true\n return item.title.toLowerCase().includes(needle)\n || item.prompt.toLowerCase().includes(needle)\n || item.sourceLabel.toLowerCase().includes(needle)\n })\n }, [list, query, category])\n\n // Escape backs out of the detail view first, then closes the modal.\n useEffect(() => {\n const onKey = (event: KeyboardEvent): void => {\n if (event.key !== 'Escape') return\n event.stopPropagation()\n if (selected !== null) setSelected(null)\n else onClose()\n }\n window.addEventListener('keydown', onKey, true)\n return () => window.removeEventListener('keydown', onKey, true)\n }, [selected, onClose])\n\n const refresh = async (): Promise<void> => {\n if (refreshing) return\n setRefreshing(true)\n setNotice(null)\n try {\n const result = await api.templatesRefresh()\n const reloaded = await api.templatesList()\n setList(reloaded)\n setLoadError(null)\n setNotice(tt('templates.refreshed', { count: result.total }))\n } catch (caught) {\n setNotice(tt('templates.refreshFailed', { error: errorMessage(caught) }))\n } finally {\n setRefreshing(false)\n }\n }\n\n /** Mirror every reference image through the host cache (offline browsing). */\n const cacheAllImages = async (): Promise<void> => {\n if (cacheAll.running || list === null) return\n const files = [...new Set(list.cases.map(item => item.image).filter(name => name !== ''))]\n setCacheAll({ running: true, done: 0, total: files.length })\n let index = 0\n const worker = async (): Promise<void> => {\n while (index < files.length) {\n const file = files[index]!\n index += 1\n try {\n await fetch(`${TEMPLATES_API.image}/${encodeURIComponent(file)}`)\n } catch { /* individual failures are retried on the next run */ }\n setCacheAll(current => ({ ...current, done: current.done + 1 }))\n }\n }\n await Promise.all(Array.from({ length: CACHE_ALL_CONCURRENCY }, () => worker()))\n setCacheAll({ running: false, done: files.length, total: files.length })\n }\n\n const copyPrompt = async (text: string): Promise<void> => {\n try {\n if (navigator.clipboard?.writeText !== undefined) {\n await navigator.clipboard.writeText(text)\n } else {\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 const copiedOk = document.execCommand('copy')\n textarea.remove()\n if (!copiedOk) throw new Error('copy failed')\n }\n setCopied(true)\n window.setTimeout(() => { setCopied(false) }, 1800)\n } catch {\n setCopied(false)\n }\n }\n\n const originLabel = list === null ? '' : tt(list.origin === 'refreshed' ? 'templates.origin.refreshed' : 'templates.origin.bundled')\n\n return createPortal(\n <div className={css.overlay} role=\"dialog\" aria-modal=\"true\" aria-label={tt('templates.title')} onClick={onClose}>\n <section className={css.shell} onClick={(event) => { event.stopPropagation() }}>\n <header className={css.header}>\n <span className={css.heading}>\n <h3 className={css.title}>{tt('templates.title')}</h3>\n {list !== null ? (\n <span className={css.meta}>{tt('templates.meta', { count: list.total, origin: originLabel })}</span>\n ) : null}\n </span>\n <span className={css.headerActions}>\n <Button variant=\"outline\" size=\"sm\" disabled={refreshing || cacheAll.running} onClick={() => { void refresh() }}>\n {refreshing ? tt('templates.refreshing') : tt('templates.refresh')}\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={list === null || cacheAll.running}\n title={tt('templates.cacheAllHint')}\n onClick={() => { void cacheAllImages() }}\n >\n {cacheAll.running\n ? tt('templates.caching', { done: cacheAll.done, total: cacheAll.total })\n : cacheAll.total > 0 && cacheAll.done === cacheAll.total\n ? tt('templates.cached')\n : tt('templates.cacheAll')}\n </Button>\n <button type=\"button\" className={css.close} aria-label={tt('templates.close')} title={tt('templates.close')} onClick={onClose}>\n <svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" aria-hidden=\"true\"><path d=\"M4 4l8 8M12 4l-8 8\"/></svg>\n </button>\n </span>\n </header>\n\n <div className={css.toolbar}>\n <input\n ref={searchRef}\n type=\"search\"\n className={css.search}\n placeholder={tt('templates.search')}\n value={query}\n onChange={(event) => { setQuery(event.target.value) }}\n />\n <div className={css.categoryRow}>\n <button\n type=\"button\"\n className={css.categoryPill}\n data-active={category === '' ? '' : undefined}\n onClick={() => { setCategory('') }}\n >\n {tt('templates.all')}{list !== null ? ` ${list.total}` : ''}\n </button>\n {categories.map(entry => (\n <button\n key={entry.key}\n type=\"button\"\n className={css.categoryPill}\n data-active={category === entry.key ? '' : undefined}\n onClick={() => { setCategory(entry.key) }}\n >\n {entry.label} {entry.count}\n </button>\n ))}\n </div>\n </div>\n\n {notice !== null ? <div className={css.notice} role=\"status\">{notice}</div> : null}\n\n <div className={css.body}>\n {list === null && loadError === null ? (\n <div className={css.state} role=\"status\">\n <span className={css.spinner} />\n <span>{tt('templates.loading')}</span>\n </div>\n ) : null}\n\n {loadError !== null ? (\n <div className={css.state} role=\"alert\">\n <span>{tt('templates.loadFailed', { error: loadError })}</span>\n <Button variant=\"outline\" size=\"sm\" onClick={() => { setLoadError(null); setList(null); load() }}>\n {tt('templates.retry')}\n </Button>\n </div>\n ) : null}\n\n {list !== null && filtered.length === 0 ? (\n <div className={css.state}>{tt('templates.empty')}</div>\n ) : null}\n\n {list !== null && filtered.length > 0 ? (\n <div className={css.grid}>\n {filtered.map(item => (\n <button\n key={item.id}\n type=\"button\"\n className={css.card}\n onClick={() => { setSelected(item); setCopied(false) }}\n >\n <span className={css.thumbWrap}>\n <TemplateThumb item={item} />\n {item.featured ? <span className={css.featuredBadge}>{tt('templates.featured')}</span> : null}\n </span>\n <span className={css.cardBody}>\n <span className={css.cardTitle}>{item.title}</span>\n <span className={css.cardMeta}>\n <span className={css.cardCategory}>{item.categoryZh || item.category}</span>\n {item.sourceLabel !== '' ? <span className={css.cardSource}>{item.sourceLabel}</span> : null}\n </span>\n </span>\n </button>\n ))}\n </div>\n ) : null}\n </div>\n\n <footer className={css.footer}>\n <span className={css.attribution}>{tt('templates.attribution')}</span>\n <a className={css.sourceLink} href=\"https://vibeui.top/\" target=\"_blank\" rel=\"noreferrer\">\n {tt('templates.source')}\n </a>\n </footer>\n </section>\n\n {selected !== null ? (\n <div className={css.detailOverlay} onClick={() => { setSelected(null) }}>\n <section className={css.detail} onClick={(event) => { event.stopPropagation() }}>\n <div className={css.detailMedia}>\n {selected.image !== '' ? (\n <img className={css.detailImage} src={imageUrlOf(selected)} alt={selected.title} />\n ) : (\n <span className={css.thumbPlaceholder} aria-hidden=\"true\" />\n )}\n </div>\n <div className={css.detailInfo}>\n <h4 className={css.detailTitle}>{selected.title}</h4>\n <div className={css.detailMeta}>\n <span className={css.cardCategory}>{selected.categoryZh || selected.category}</span>\n {selected.sourceUrl !== '' ? (\n <a className={css.detailLink} href={selected.sourceUrl} target=\"_blank\" rel=\"noreferrer\">{selected.sourceLabel || selected.sourceUrl}</a>\n ) : null}\n {selected.githubUrl !== '' ? (\n <a className={css.detailLink} href={selected.githubUrl} target=\"_blank\" rel=\"noreferrer\">GitHub</a>\n ) : null}\n </div>\n <pre className={css.detailPrompt}>{selected.prompt}</pre>\n <div className={css.detailActions}>\n <Button variant=\"primary\" size=\"md\" onClick={() => { onUse(selected.prompt) }}>\n {tt('templates.use')}\n </Button>\n <Button variant=\"outline\" size=\"md\" onClick={() => { void copyPrompt(selected.prompt) }}>\n {copied ? tt('templates.copied') : tt('templates.copy')}\n </Button>\n <Button variant=\"outline\" size=\"md\" onClick={() => { setSelected(null) }}>\n {tt('templates.back')}\n </Button>\n </div>\n </div>\n </section>\n </div>\n ) : null}\n </div>,\n document.body,\n )\n}\n","/**\n * Browser-side settings scope for the dsh-imagegen namespace, served by the\n * plugin's own loopback bridge routes (/api/dsh-imagegen/settings). The\n * official rc.6 settings scope answers \"unavailable\" for every third-party\n * namespace (the host-apiproxy allowlist is hard-coded), so this package\n * re-serves its namespace through the host settings seam over a same-origin,\n * loopback-only HTTP pair — the same pattern the dsh-web-ui family bridge\n * uses, self-contained per plugin.\n */\n\nimport {\n createSnapshotStore,\n type SettingsScope,\n type SettingsScopeSnapshot,\n type SnapshotStore,\n} from '@deepseek-ai/dsh-client-runtime/client'\nimport { SETTINGS_API, type ChannelConfig } from '../protocol.ts'\n\n/** The fields this plugin's settings card edits. */\nexport interface ImageGenConfig {\n enabled?: boolean\n announceToAgent?: boolean\n allowAgentImageGeneration?: boolean\n /** Configured channels (each: name, endpoint, model catalog). */\n channels?: ChannelConfig[]\n /** Per-channel API keys, keyed by channel id. The redacted wire view returns\n * this as an empty object; key presence comes from the secrets sidecar. */\n channelSecrets?: Record<string, string>\n /** Channel used when a request does not name one. */\n defaultChannelId?: string\n promptApiUrl?: string\n promptApiKey?: string\n promptModel?: string\n /* ----- deprecated legacy single-endpoint fields (migrated to channels) ----- */\n apiUrl?: string\n apiKey?: string\n imageModels?: string[]\n}\n\n/** One settings path-op as the bridge consumes it. */\nexport type SettingsOp = { op: 'set'; path: string[]; value: unknown } | { op: 'unset'; path: string[] }\n\n/** Wire shape of one namespace view from the bridge. */\ninterface BridgeView {\n ns: string\n value: unknown\n base?: unknown\n user?: unknown\n revision: number\n secrets?: Array<{ path: string[]; set: boolean }>\n}\n\n/** The bridge response envelope ({ ok: true, value } | { ok: false, code, message }). */\ntype BridgeEnvelope =\n | { ok: true; value: { namespaces?: BridgeView[]; writable?: boolean } | BridgeView }\n | { ok: false; code: string; message: string }\n\n/** Settings wire face over the bridge routes (fetch-backed). */\nfunction createBridgeApi(fetchFn: typeof fetch): {\n settings: {\n describe(payload: Record<string, never>): Promise<{ result: BridgeEnvelope }>\n mutate(payload: { ns: string; ops: unknown[]; expectedRevision?: number }): Promise<{ result: BridgeEnvelope }>\n }\n} {\n const post = async (path: string, body: unknown): Promise<{ result: BridgeEnvelope }> => {\n try {\n const response = await fetchFn(path, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n })\n if (!response.ok) {\n return { result: { ok: false, code: 'internal', message: `bridge HTTP ${response.status}` } }\n }\n return { result: await response.json() as BridgeEnvelope }\n } catch {\n return { result: { ok: false, code: 'internal', message: 'settings bridge unreachable' } }\n }\n }\n return {\n settings: {\n describe: async payload => post(SETTINGS_API.describe, payload),\n mutate: async payload => post(SETTINGS_API.mutate, payload),\n },\n }\n}\n\n/**\n * A SettingsScope over the bridge face: serialized queue, revision-fenced\n * writes, recovery read after a refusal. Mirrors the official controller's\n * ordering but trusts the Host-seam value without re-running the wire-schema\n * validation — the seam already validated it.\n */\nclass BridgeScopeController<T> implements SettingsScope<T> {\n private readonly store: SnapshotStore<SettingsScopeSnapshot<T>>\n /** Whether the namespace currently holds a stored secret (e.g. apiKey). */\n private readonly keySet: SnapshotStore<boolean>\n /** Individual secret presence bits, keyed by the settings field name. */\n private readonly secretSets: SnapshotStore<Record<string, boolean>>\n private tail: Promise<void> = Promise.resolve()\n private disposed = false\n\n constructor(\n private readonly api: ReturnType<typeof createBridgeApi>['settings'],\n private readonly spec: { namespace: string },\n ) {\n this.store = createSnapshotStore<SettingsScopeSnapshot<T>>({\n status: 'loading',\n value: undefined,\n base: undefined,\n user: undefined,\n revision: undefined,\n writable: false,\n mode: 'host',\n })\n this.keySet = createSnapshotStore(false)\n this.secretSets = createSnapshotStore({})\n }\n\n getSnapshot(): SettingsScopeSnapshot<T> {\n return this.store.getSnapshot()\n }\n\n /** Whether a stored secret exists (from the redacted view's secrets list). */\n getKeySetSnapshot(): boolean {\n return this.keySet.getSnapshot()\n }\n\n /** Observe the secret-set flag. */\n subscribeKeySet(listener: () => void): () => void {\n return this.keySet.subscribe(listener)\n }\n\n /** Whether a specific secret field currently has a stored value. */\n getSecretSetSnapshot(field: string): boolean {\n return this.secretSets.getSnapshot()[field] === true\n }\n\n /** Observe changes to individual secret-field presence bits. */\n subscribeSecretSets(listener: () => void): () => void {\n return this.secretSets.subscribe(listener)\n }\n\n subscribe(listener: () => void): () => void {\n return this.store.subscribe(listener)\n }\n\n /** Queue a bridge refresh. */\n load(): Promise<void> {\n return this.enqueue(() => this.read())\n }\n\n set(field: string, value: unknown): Promise<void> {\n return this.enqueue(() => this.writeOps([{ op: 'set', path: [field], value }]))\n }\n\n unset(field: string): Promise<void> {\n return this.enqueue(() => this.writeOps([{ op: 'unset', path: [field] }]))\n }\n\n /** Apply several path ops in one revision-fenced mutate call (atomic save).\n * Path ops may address plain-object fields (e.g. `channelSecrets.<id>`),\n * but never navigate *inside* arrays — write array fields wholesale. */\n mutateOps(ops: SettingsOp[]): Promise<void> {\n return this.enqueue(() => this.writeOps(ops))\n }\n\n async dispose(): Promise<void> {\n this.disposed = true\n await this.tail\n }\n\n private enqueue(operation: () => Promise<void>): Promise<void> {\n if (this.disposed) return Promise.resolve()\n const task = this.tail.then(async () => {\n if (this.disposed) return\n await operation()\n })\n this.tail = task.catch(() => {})\n return task\n }\n\n private async read(): Promise<void> {\n let response\n try {\n response = await this.api.describe({})\n } catch {\n if (!this.disposed) this.store.update(draft => { draft.status = 'unavailable' })\n return\n }\n if (!response.result.ok || this.disposed) {\n if (!this.disposed) this.store.update(draft => { draft.status = 'unavailable' })\n return\n }\n const { namespaces, writable } = response.result.value as { namespaces?: BridgeView[]; writable?: boolean }\n const view = namespaces?.find(candidate => candidate.ns === this.spec.namespace)\n if (view === undefined) {\n this.store.update(draft => {\n draft.status = 'unavailable'\n draft.writable = writable === true\n })\n this.keySet.set(false)\n this.secretSets.set({})\n return\n }\n this.accept(view, writable)\n }\n\n private async writeOps(ops: SettingsOp[]): Promise<void> {\n const revision = this.getSnapshot().revision\n let response\n try {\n response = await this.api.mutate({\n ns: this.spec.namespace,\n ops,\n ...revision === undefined ? {} : { expectedRevision: revision },\n })\n } catch {\n await this.read()\n return\n }\n if (!response.result.ok || this.disposed) {\n await this.read()\n return\n }\n this.accept(response.result.value as BridgeView, undefined)\n }\n\n private accept(view: BridgeView, writable: boolean | undefined): void {\n this.store.update(draft => {\n draft.revision = view.revision\n draft.base = view.base\n draft.user = view.user\n if (writable !== undefined) draft.writable = writable\n draft.status = 'ready'\n // Trust the Host-seam value: the seam already validated it, and the\n // card binds without a narrowing decoder.\n draft.value = view.value as T\n })\n const secretSets = Object.fromEntries((view.secrets ?? []).map(secret => [secret.path.join('.'), secret.set]))\n this.keySet.set(Object.values(secretSets).some(Boolean))\n this.secretSets.set(secretSets)\n }\n}\n\n/** The bound scope plus the secret-set flag, as the card and panel consume it. */\nexport interface ImageGenScope extends SettingsScope<ImageGenConfig> {\n /** Queue a bridge refresh (the invalidation path re-reads the namespace). */\n load(): Promise<void>\n /** Apply several path ops in one revision-fenced mutate call. */\n mutateOps(ops: SettingsOp[]): Promise<void>\n getKeySetSnapshot(): boolean\n subscribeKeySet(listener: () => void): () => void\n getSecretSetSnapshot(field: string): boolean\n subscribeSecretSets(listener: () => void): () => void\n}\n\n/**\n * Bind the dsh-imagegen settings scope over the bridge routes and start its\n * initial read (the caller mounts nothing until the scope settles).\n * @param fetchFn - the fetch implementation (the global fetch on loopback).\n * @returns the scope; unavailable when the bridge is unreachable.\n */\nexport function bindImageGenScope(fetchFn: typeof fetch = fetch): ImageGenScope {\n const controller = new BridgeScopeController<ImageGenConfig>(createBridgeApi(fetchFn).settings, {\n namespace: 'dsh-imagegen',\n })\n void controller.load()\n return controller\n}\n\n/**\n * Flatten the configured channels into the model options the panel lists\n * (aliases; the default channel's models first) plus the default channel id.\n * Falls back to the legacy flat allow-list while no channels exist (upgrade\n * path). Pure projection — no host calls.\n */\nexport function imageModelOptions(config: ImageGenConfig | undefined): { models: string[]; defaultChannelId?: string } {\n const channels = config?.channels ?? []\n if (channels.length === 0) {\n const legacy = Array.isArray(config?.imageModels)\n ? config.imageModels.filter((model): model is string => typeof model === 'string' && model.trim() !== '')\n : []\n return { models: legacy }\n }\n const defaultId = config?.defaultChannelId !== undefined && channels.some(channel => channel.id === config.defaultChannelId)\n ? config.defaultChannelId\n : channels[0]!.id\n const ordered = [defaultId, ...channels.filter(channel => channel.id !== defaultId).map(channel => channel.id)]\n const models: string[] = []\n for (const id of ordered) {\n const channel = channels.find(candidate => candidate.id === id)!\n for (const model of channel.models) {\n if (model.alias !== '' && !models.includes(model.alias)) models.push(model.alias)\n }\n }\n return models.length > 0 ? { models, defaultChannelId: defaultId } : { models: [], defaultChannelId: defaultId }\n}\n","/**\n * Image-model configuration shared by the host, panel, and Agent tools.\n * `/models` exposes candidates only: the configured list is the explicit\n * allow-list because OpenAI-compatible gateways rarely advertise modalities.\n */\n\nexport const DEFAULT_IMAGE_MODELS = ['gpt-image-2', 'grok-imagine-image', 'nanobanana2', 'nanobanana2-lite', 'nanobanana-pro', 'seedream-5.0-pro'] as const\n\n/** Normalize user-entered model identifiers and retain a usable legacy default. */\nexport function normalizeImageModels(value: unknown): string[] {\n const candidates = Array.isArray(value) ? value : []\n const unique = new Set<string>()\n for (const candidate of candidates) {\n if (typeof candidate !== 'string') continue\n const model = candidate.trim()\n if (model !== '') unique.add(model)\n }\n return unique.size > 0 ? [...unique] : [...DEFAULT_IMAGE_MODELS]\n}\n","/**\n * The AI 生图 studio: a three-column layout — left, a card-grouped\n * configuration sidebar (mode tabs, prompt with counter, rounded parameter\n * selectors, model dropdown + generate button); center, the result canvas;\n * right, a persistent generation history column.\n *\n * Controls ride the system UI primitives (@deepseek-ai/dsh-client-ui-primitives,\n * a platform module) so the studio matches the dsh shell look by construction.\n */\n\nimport { useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport { Button, Pill } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { ImageGenApi } from './api.ts'\nimport { errorMessage, tt } from './helpers.ts'\nimport { TemplateLibrary } from './TemplateLibrary.tsx'\nimport type { GeneratedImage, GenerateMode, GenerateRequest, GenerationTask, HistoryEntry, HistoryImageRef, UpdateInfo } from '../protocol.ts'\nimport type { ImageGenConfig, ImageGenScope } from './settings-scope.ts'\nimport { imageModelOptions } from './settings-scope.ts'\nimport { normalizeImageModels } from '../image-models.ts'\nimport css from './panel.module.css'\n\n/** Size options, presented as aspect ratios (auto = let the model decide).\n * The host maps each ratio onto the model's own vocabulary: aspect_ratio for\n * Grok Imagine, the closest pixel size for OpenAI-compatible endpoints. */\nconst SIZES = ['auto', '1:1', '3:4', '4:3', '9:16', '2:3', '3:2', '16:9', '21:9'] as const\n\n/** Size option keys in the locale dictionary. */\nconst SIZE_KEYS: Record<string, 'size.auto' | 'size.square' | 'size.portrait34' | 'size.landscape43' | 'size.portrait916' | 'size.portrait23' | 'size.landscape32' | 'size.wide169' | 'size.ultrawide21'> = {\n auto: 'size.auto',\n '1:1': 'size.square',\n '3:4': 'size.portrait34',\n '4:3': 'size.landscape43',\n '9:16': 'size.portrait916',\n '2:3': 'size.portrait23',\n '3:2': 'size.landscape32',\n '16:9': 'size.wide169',\n '21:9': 'size.ultrawide21',\n}\n\n/** Quality options, shown as output-resolution tiers (auto = let the model\n * decide). The host maps them: resolution for Grok, quality level for\n * OpenAI-compatible endpoints (1k→low, 2k→medium, 4k→high). */\nconst QUALITIES = ['auto', '1k', '2k', '4k'] as const\n\n/** Detail options ('' = omit the passthrough). */\nconst DETAILS = ['', 'standard', 'high'] as const\n\nconst REF_IMAGE_MAX_BYTES = 10 * 1024 * 1024\nconst PREVIEW_SCALE_MIN = 0.5\nconst PREVIEW_SCALE_MAX = 3\nconst PREVIEW_SCALE_STEP = 0.25\n\n/** Legacy pixel sizes saved by older versions, mapped onto the current\n * aspect-ratio vocabulary so restoring old history entries still works. */\nconst LEGACY_SIZE_TO_RATIO: Record<string, string> = {\n '512x512': '1:1',\n '1024x1024': '1:1',\n '1536x1024': '3:2',\n '1024x1536': '2:3',\n '1792x1024': '16:9',\n '1024x1792': '9:16',\n}\n\n/** Legacy quality levels saved by older versions, mapped onto resolution. */\nconst LEGACY_QUALITY_TO_RES: Record<string, string> = {\n low: '1k',\n medium: '2k',\n high: '4k',\n}\n\n/** Normalize a saved size value into a current dropdown option. */\nfunction normalizeSize(value: string): string {\n if ((SIZES as readonly string[]).includes(value)) return value\n return LEGACY_SIZE_TO_RATIO[value] ?? 'auto'\n}\n\n/** Normalize a saved quality value into a current dropdown option. */\nfunction normalizeQuality(value: string): string {\n if ((QUALITIES as readonly string[]).includes(value)) return value\n return LEGACY_QUALITY_TO_RES[value] ?? 'auto'\n}\n\nfunction clampPreviewScale(scale: number): number {\n return Math.min(PREVIEW_SCALE_MAX, Math.max(PREVIEW_SCALE_MIN, scale))\n}\n\n/** Read the current config from the settings scope snapshot. */\nfunction useConfig(scope: ImageGenScope): ImageGenConfig | undefined {\n const [value, setValue] = useState(scope.getSnapshot().value)\n useEffect(() => scope.subscribe(() => { setValue(scope.getSnapshot().value) }), [scope])\n return value\n}\n\n/** Track one redacted secret field without exposing its value to the panel. */\nfunction useSecretSet(scope: ImageGenScope, field: string): boolean {\n const [isSet, setIsSet] = useState(scope.getSecretSetSnapshot(field))\n useEffect(() => scope.subscribeSecretSets(() => { setIsSet(scope.getSecretSetSnapshot(field)) }), [field, scope])\n return isSet\n}\n\n/** Tick a seconds counter while `running`. */\nfunction useElapsed(running: boolean, startedAt: number | null): number {\n const [elapsed, setElapsed] = useState(0)\n useEffect(() => {\n if (!running || startedAt === null) {\n setElapsed(0)\n return\n }\n const update = (): void => {\n setElapsed(Math.max(1, Math.round((Date.now() - startedAt) / 1000)))\n }\n update()\n const timer = window.setInterval(update, 1000)\n return () => window.clearInterval(timer)\n }, [running, startedAt])\n return elapsed\n}\n\n/** Data URL for a generated image. */\nfunction srcOf(image: GeneratedImage): string {\n return `data:${image.mime};base64,${image.b64}`\n}\n\n/** Fetch persisted history image refs and decode them back to in-memory\n * GeneratedImage[] (base64), so the canvas/preview can reuse the same\n * rendering path as a fresh generation. */\nasync function historyImagesToGenerated(refs: HistoryImageRef[]): Promise<GeneratedImage[]> {\n return Promise.all(refs.map(async ref => {\n const response = await fetch(ref.url)\n if (!response.ok) throw new Error(`HTTP ${response.status}`)\n const blob = await response.blob()\n const dataUrl = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => resolve(typeof reader.result === 'string' ? reader.result : '')\n reader.onerror = () => reject(new Error('image read failed'))\n reader.readAsDataURL(blob)\n })\n const comma = dataUrl.indexOf(',')\n return {\n b64: comma >= 0 ? dataUrl.slice(comma + 1) : '',\n mime: ref.mime,\n ...ref.revisedPrompt === undefined ? {} : { revisedPrompt: ref.revisedPrompt },\n }\n }))\n}\n\n/** Compact, locale-independent timestamp for history entries. */\nfunction formatTime(timestamp: number): string {\n const d = new Date(timestamp)\n const pad = (n: number): string => String(n).padStart(2, '0')\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`\n}\n\n/** Studio tabs: the two generation modes plus the gallery view. */\ntype PanelTab = GenerateMode | 'gallery'\n\ntype GalleryFilter = string\ntype ComparisonSession = { taskIds: string[]; prompt: string }\n\n/** Render the studio. */\nexport function ImageGenPanel(props: {\n api: ImageGenApi\n scope: ImageGenScope\n}) {\n const { api, scope } = props\n const config = useConfig(scope)\n const enabled = config?.enabled ?? true\n // Channel-aware model options: the panel lists every configured alias\n // (default channel first); legacy flat fields remain the upgrade fallback.\n const modelOptions = imageModelOptions(config)\n const hasChannels = (config?.channels ?? []).length > 0\n // With channels configured, the model list is exactly the configured aliases\n // (possibly empty — never fall back to the hardcoded legacy defaults).\n const imageModels = hasChannels ? modelOptions.models : normalizeImageModels(config?.imageModels)\n const defaultChannelId = modelOptions.defaultChannelId\n const apiUrl = defaultChannelId !== undefined && (config?.channels ?? []).length > 0\n ? (config!.channels!.find(channel => channel.id === defaultChannelId)?.apiUrl ?? '')\n : (config?.apiUrl ?? '')\n const configured = apiUrl.trim() !== ''\n const legacyKeySet = useSecretSet(scope, 'apiKey')\n const promptKeySet = useSecretSet(scope, 'promptApiKey')\n const channelKeySet = (config?.channels ?? []).some(channel => scope.getSecretSetSnapshot(`channelSecrets.${channel.id}`))\n const apiKeySet = (config?.channels ?? []).length > 0 ? channelKeySet : legacyKeySet\n const connected = enabled && configured && apiKeySet\n\n const [tab, setTab] = useState<PanelTab>('text')\n const [prompt, setPrompt] = useState('')\n const [size, setSize] = useState<string>('auto')\n const [quality, setQuality] = useState<string>('auto')\n const [count, setCount] = useState(1)\n const [detail, setDetail] = useState('')\n const [model, setModel] = useState<string>('')\n const [compareEnabled, setCompareEnabled] = useState(false)\n const [compareModels, setCompareModels] = useState<string[]>([])\n const [modelOpen, setModelOpen] = useState(false)\n const [refImage, setRefImage] = useState<{ dataUrl: string; name: string } | null>(null)\n const [images, setImages] = useState<GeneratedImage[]>([])\n const [error, setError] = useState<string | null>(null)\n // Submission is brief; actual generation stays visible until the host\n // queue reports that every queued/running task has finished.\n const [submitting, setSubmitting] = useState(false)\n const [enhancing, setEnhancing] = useState(false)\n const [configGuide, setConfigGuide] = useState<'generation' | 'enhancement' | 'disabled' | null>(null)\n const [history, setHistory] = useState<HistoryEntry[]>([])\n const [viewingHistoryId, setViewingHistoryId] = useState<string | null>(null)\n const [gallery, setGallery] = useState<HistoryEntry[]>([])\n const [galleryViewingId, setGalleryViewingId] = useState<string | null>(null)\n const [galleryAdding, setGalleryAdding] = useState(false)\n const [galleryMessage, setGalleryMessage] = useState<string | null>(null)\n const [galleryFilter, setGalleryFilter] = useState<GalleryFilter>('all')\n const [galleryRatio, setGalleryRatio] = useState('all')\n const [galleryTagFilter, setGalleryTagFilter] = useState<string | null>(null)\n const [galleryView, setGalleryView] = useState<'masonry' | 'grid'>('masonry')\n const [gallerySort, setGallerySort] = useState<'newest' | 'oldest'>('newest')\n const [galleryQuery, setGalleryQuery] = useState('')\n const [galleryTagInput, setGalleryTagInput] = useState('')\n const [editingGalleryTagsId, setEditingGalleryTagsId] = useState<string | null>(null)\n const [galleryTagEditInput, setGalleryTagEditInput] = useState('')\n const [selectedGalleryIds, setSelectedGalleryIds] = useState<Set<string>>(new Set())\n const [gallerySelecting, setGallerySelecting] = useState(false)\n const [historyQuery, setHistoryQuery] = useState('')\n const [historyModelFilter, setHistoryModelFilter] = useState('all')\n const [historyRatioFilter, setHistoryRatioFilter] = useState('all')\n const [preview, setPreview] = useState<{ images: GeneratedImage[]; index: number } | null>(null)\n const [previewScale, setPreviewScale] = useState(1)\n const [promptCopied, setPromptCopied] = useState(false)\n const [update, setUpdate] = useState<UpdateInfo | null>(null)\n const [updating, setUpdating] = useState(false)\n const [updateMessage, setUpdateMessage] = useState<string | null>(null)\n const [updateResult, setUpdateResult] = useState<'success' | 'failed' | null>(null)\n const [libraryOpen, setLibraryOpen] = useState(false)\n const [tasks, setTasks] = useState<GenerationTask[]>([])\n const [taskTrayOpen, setTaskTrayOpen] = useState(false)\n const [comparison, setComparison] = useState<ComparisonSession | null>(null)\n const [comparisonFullscreen, setComparisonFullscreen] = useState(false)\n const fileInput = useRef<HTMLInputElement>(null)\n const previewStage = useRef<HTMLDivElement>(null)\n const activeTasks = tasks.filter(task => task.status === 'queued' || task.status === 'running')\n const activeTask = activeTasks.find(task => task.status === 'running') ?? activeTasks[0]\n const generating = submitting || activeTasks.length > 0\n const generationStartedAt = activeTask?.startedAt ?? activeTask?.createdAt ?? null\n const elapsed = useElapsed(generating, generationStartedAt)\n\n // A saved settings change is authoritative. Keep the active selection and\n // comparison choices in that allow-list without disturbing valid choices.\n const imageModelKey = imageModels.join('\\u0000')\n useEffect(() => {\n setModel(previous => imageModels.includes(previous) ? previous : imageModels[0])\n setCompareModels(previous => {\n const retained = previous.filter(candidate => imageModels.includes(candidate))\n return retained.length > 0 ? retained : [imageModels[0]]\n })\n }, [imageModelKey])\n\n const filteredGallery = gallery\n .filter(entry => {\n if (galleryFilter === 'all') return true\n if (galleryFilter === 'text' || galleryFilter === 'edit') return entry.mode === galleryFilter\n return entry.model === galleryFilter\n })\n .filter(entry => galleryRatio === 'all' || normalizeSize(entry.size) === galleryRatio)\n .filter(entry => galleryTagFilter === null || (entry.tags ?? []).includes(galleryTagFilter))\n .filter(entry => galleryQuery.trim() === '' || `${entry.prompt} ${entry.model} ${(entry.tags ?? []).join(' ')}`.toLocaleLowerCase().includes(galleryQuery.trim().toLocaleLowerCase()))\n .slice()\n .sort((a, b) => gallerySort === 'newest' ? b.createdAt - a.createdAt : a.createdAt - b.createdAt)\n\n const galleryTagOptions = [...new Set(gallery.flatMap(entry => entry.tags ?? []))].sort((a, b) => a.localeCompare(b))\n const galleryModels = [...new Set([...imageModels, ...gallery.map(entry => entry.model)])]\n\n const filteredHistory = history.filter(entry => {\n const query = historyQuery.trim().toLocaleLowerCase()\n return (query === '' || `${entry.prompt} ${entry.model}`.toLocaleLowerCase().includes(query))\n && (historyModelFilter === 'all' || entry.model === historyModelFilter)\n && (historyRatioFilter === 'all' || normalizeSize(entry.size) === historyRatioFilter)\n })\n\n // Load the host-persisted history and gallery once on mount (they live in\n // ~/.dsh on the DSH host, so every browser/device sees the same lists).\n useEffect(() => {\n let disposed = false\n api.historyList()\n .then(entries => { if (!disposed) setHistory(entries) })\n .catch(() => { /* history unavailable — leave the list empty */ })\n api.galleryList()\n .then(entries => { if (!disposed) setGallery(entries) })\n .catch(() => { /* gallery unavailable — leave the list empty */ })\n return () => { disposed = true }\n }, [api])\n\n useEffect(() => {\n let disposed = false\n const refresh = (): void => {\n void api.taskList().then(next => {\n if (disposed) return\n setTasks(previous => {\n const completed = next.find(task => task.status === 'completed'\n && !previous.some(old => old.id === task.id && old.status === 'completed')\n && !comparison?.taskIds.includes(task.id))\n if (completed?.result !== undefined) {\n setImages(completed.result.images)\n if (completed.result.history !== undefined) setHistory(completed.result.history)\n setError(completed.result.historyError ?? null)\n }\n return next\n })\n }).catch(() => {})\n }\n refresh()\n const timer = window.setInterval(refresh, 1500)\n return () => { disposed = true; window.clearInterval(timer) }\n }, [api, comparison])\n\n // Close the model dropdown when clicking anywhere outside it.\n const modelMenuRef = useRef<HTMLDivElement>(null)\n useEffect(() => {\n if (!modelOpen) return\n const onPointer = (event: MouseEvent | FocusEvent): void => {\n const target = event.target\n if (target instanceof Node && modelMenuRef.current?.contains(target)) return\n setModelOpen(false)\n }\n document.addEventListener('mousedown', onPointer)\n document.addEventListener('focusin', onPointer)\n return () => {\n document.removeEventListener('mousedown', onPointer)\n document.removeEventListener('focusin', onPointer)\n }\n }, [modelOpen])\n\n // Release checks are host-mediated and intentionally best-effort: a GitHub\n // outage must never make the image-generation studio unavailable.\n useEffect(() => {\n let disposed = false\n api.updateCheck()\n .then(info => {\n if (!disposed && info.updateAvailable) setUpdate(info)\n })\n .catch(() => { /* update discovery is optional */ })\n return () => { disposed = true }\n }, [api])\n\n const applyUpdate = async (): Promise<void> => {\n if (update === null || updating) return\n setUpdating(true)\n setUpdateMessage(null)\n setUpdateResult(null)\n try {\n const result = await api.updateApply(update.latestVersion)\n setUpdateMessage(tt('update.success', { version: result.updatedVersion }))\n setUpdateResult('success')\n } catch {\n setUpdateMessage(tt('update.failed'))\n setUpdateResult('failed')\n } finally {\n setUpdating(false)\n }\n }\n\n const openSettingsGuide = (kind: 'generation' | 'enhancement' | 'disabled'): void => {\n setConfigGuide(kind)\n const openPluginSettings = (): void => {\n const pluginButton = Array.from(document.querySelectorAll<HTMLButtonElement>('button')).find(button => /^(插件|Plugins)$/.test(button.textContent?.trim() ?? ''))\n pluginButton?.click()\n window.setTimeout(() => {\n const imageGenButton = Array.from(document.querySelectorAll<HTMLButtonElement>('button')).find(button => /dsh-imagegen/i.test(button.textContent ?? ''))\n if (imageGenButton?.getAttribute('aria-expanded') !== 'true') imageGenButton?.click()\n }, 0)\n }\n const settingsButton = Array.from(document.querySelectorAll<HTMLButtonElement>('button')).find(button => /^(设置|Settings)$/.test(button.textContent?.trim() ?? ''))\n if (settingsButton?.getAttribute('aria-expanded') !== 'true') settingsButton?.click()\n window.setTimeout(openPluginSettings, 0)\n }\n\n const enhanceCurrentPrompt = async (): Promise<void> => {\n if (prompt.trim() === '' || enhancing) return\n const promptEndpointConfigured = (config?.promptApiUrl ?? '').trim() !== '' || configured\n if ((config?.promptModel ?? '').trim() === '' || !promptEndpointConfigured || (!promptKeySet && !apiKeySet)) {\n openSettingsGuide('enhancement')\n return\n }\n setEnhancing(true)\n setError(null)\n try {\n setPrompt(await api.enhancePrompt(prompt))\n } catch (caught) {\n setError(errorMessage(caught))\n } finally {\n setEnhancing(false)\n }\n }\n\n /** Read an uploaded reference image into a data URL. */\n const acceptFile = (file: File | undefined): void => {\n if (file === undefined) return\n if (!file.type.startsWith('image/')) {\n setError(tt('edit.uploadHint'))\n return\n }\n if (file.size > REF_IMAGE_MAX_BYTES) {\n setError(tt('edit.uploadHint'))\n return\n }\n const reader = new FileReader()\n reader.onload = () => {\n if (typeof reader.result === 'string') setRefImage({ dataUrl: reader.result, name: file.name })\n }\n reader.onerror = () => { setError(tt('edit.uploadHint')) }\n reader.readAsDataURL(file)\n }\n\n /** Run one generation. */\n const handleGenerate = async (): Promise<void> => {\n if (submitting) return\n if (!enabled) {\n openSettingsGuide('disabled')\n return\n }\n if (!configured || !apiKeySet) {\n openSettingsGuide('generation')\n return\n }\n const promptText = prompt.trim()\n if (promptText === '') {\n setError(tt('prompt.required'))\n return\n }\n if (tab === 'edit' && refImage === null) {\n setError(tt('edit.required'))\n return\n }\n const request: GenerateRequest = {\n mode: tab === 'gallery' ? 'text' : tab,\n model: imageModels.includes(model) ? model : imageModels[0],\n prompt: promptText,\n size,\n quality,\n n: count,\n detail,\n ...defaultChannelId !== undefined ? { channelId: defaultChannelId } : {},\n ...tab === 'edit' && refImage !== null ? { image: refImage.dataUrl } : {},\n ...tab === 'edit' && refImage !== null ? { refName: refImage.name } : {},\n }\n setError(null)\n setSubmitting(true)\n try {\n const targetModels = (compareEnabled ? compareModels : [request.model]).filter(candidate => imageModels.includes(candidate))\n if (targetModels.length === 0) {\n setError(tt('compare.selectRequired'))\n return\n }\n const submitted = await Promise.all(targetModels.map(targetModel => api.taskSubmit({ ...request, model: targetModel })))\n setTasks(previous => [...submitted, ...previous.filter(item => !submitted.some(task => task.id === item.id))])\n setComparison(targetModels.length > 1 ? { taskIds: submitted.map(task => task.id), prompt: promptText } : null)\n } catch (caught) {\n setError(errorMessage(caught))\n } finally {\n setSubmitting(false)\n }\n }\n\n /** Open the full-screen image preview at a given index. */\n const openPreview = (previewImages: GeneratedImage[], index: number): void => {\n setPreview({ images: previewImages, index })\n setPreviewScale(1)\n setPromptCopied(false)\n }\n\n const closePreview = (): void => {\n setPreview(null)\n setPreviewScale(1)\n setPromptCopied(false)\n }\n\n /** Step the preview by ±1, wrapping around. */\n const stepPreview = (delta: number): void => {\n setPreviewScale(1)\n setPromptCopied(false)\n setPreview(current => {\n if (current === null) return null\n const total = current.images.length\n return { images: current.images, index: (current.index + delta + total) % total }\n })\n }\n\n // Keyboard navigation for the preview overlay.\n useEffect(() => {\n if (preview === null) return\n const onKey = (event: KeyboardEvent): void => {\n if (event.key === 'Escape') closePreview()\n else if (event.key === 'ArrowLeft') stepPreview(-1)\n else if (event.key === 'ArrowRight') stepPreview(1)\n else if (event.key === '+' || event.key === '=') setPreviewScale(current => clampPreviewScale(current + PREVIEW_SCALE_STEP))\n else if (event.key === '-') setPreviewScale(current => clampPreviewScale(current - PREVIEW_SCALE_STEP))\n else if (event.key === '0') setPreviewScale(1)\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [preview])\n\n // A scaled image owns real scrollable space, rather than being visually\n // transformed and clipped. Recenter the viewport after every zoom or slide.\n useEffect(() => {\n if (preview === null) return\n const frame = window.requestAnimationFrame(() => {\n const stage = previewStage.current\n if (stage === null) return\n stage.scrollLeft = Math.max(0, (stage.scrollWidth - stage.clientWidth) / 2)\n stage.scrollTop = Math.max(0, (stage.scrollHeight - stage.clientHeight) / 2)\n })\n return () => window.cancelAnimationFrame(frame)\n }, [preview, previewScale])\n\n /** Load a past generation's images into the canvas. */\n const viewHistoryEntry = async (entry: HistoryEntry): Promise<void> => {\n try {\n setImages(await historyImagesToGenerated(entry.images))\n setError(null)\n setViewingHistoryId(entry.id)\n setGalleryViewingId(null)\n } catch (caught) {\n setError(errorMessage(caught))\n }\n }\n\n /** Restore a past generation's parameters (and its images) into the form. */\n const restoreHistoryEntry = async (entry: HistoryEntry): Promise<void> => {\n try {\n const restored = await historyImagesToGenerated(entry.images)\n setTab(entry.mode)\n setPrompt(entry.prompt)\n setSize(normalizeSize(entry.size))\n setQuality(normalizeQuality(entry.quality))\n setDetail((DETAILS as readonly string[]).includes(entry.detail) ? entry.detail : '')\n setCount(entry.n >= 1 && entry.n <= 4 ? entry.n : 1)\n setModel(imageModels.includes(entry.model) ? entry.model : imageModels[0])\n setRefImage(null)\n setImages(restored)\n setError(null)\n setViewingHistoryId(entry.id)\n setGalleryViewingId(null)\n } catch (caught) {\n setError(errorMessage(caught))\n }\n }\n\n /** Remove one history entry. */\n const deleteHistoryEntry = async (id: string): Promise<void> => {\n setHistory(history.filter(entry => entry.id !== id))\n if (viewingHistoryId === id) setViewingHistoryId(null)\n try {\n setHistory(await api.historyRemove(id))\n } catch {\n // Keep the optimistic local removal.\n }\n }\n\n /** Remove all history entries. */\n const clearHistory = async (): Promise<void> => {\n setHistory([])\n setViewingHistoryId(null)\n try {\n setHistory(await api.historyClear())\n } catch {\n // Keep the cleared local state.\n }\n }\n\n /** Add one generated image to the gallery (host deduplicates by content).\n * `entry` makes the action available from a history/gallery list item (its\n * metadata + first image are saved); otherwise the current form state is\n * used. */\n const addToGallery = async (image: GeneratedImage, entry?: HistoryEntry): Promise<void> => {\n if (galleryAdding || tab === 'gallery') return\n const source = entry ?? viewingEntry ?? {\n mode: tab === 'edit' ? 'edit' as GenerateMode : 'text' as GenerateMode,\n model,\n prompt: prompt.trim(),\n size,\n quality,\n detail,\n ...refImage !== null ? { refName: refImage.name } : {},\n }\n setGalleryAdding(true)\n try {\n const result = await api.galleryAppend({\n id: '', // the host assigns a fresh id\n createdAt: Date.now(),\n mode: source.mode,\n model: source.model,\n prompt: source.prompt,\n size: source.size,\n quality: source.quality,\n detail: source.detail,\n n: 1,\n images: [image],\n ...source.refName === undefined ? {} : { refName: source.refName },\n })\n setGallery(result.entries)\n setGalleryMessage(result.added ? tt('gallery.added') : tt('gallery.already'))\n window.setTimeout(() => { setGalleryMessage(null) }, 2200)\n } catch (caught) {\n setError(errorMessage(caught))\n } finally {\n setGalleryAdding(false)\n }\n }\n\n /** Add one history entry's first image to the gallery (fetches it from the\n * history image route, then delegates to addToGallery). */\n const addHistoryEntryToGallery = async (entry: HistoryEntry): Promise<void> => {\n if (galleryAdding || entry.images.length === 0) return\n try {\n const [image] = await historyImagesToGenerated(entry.images.slice(0, 1))\n if (image === undefined) return\n await addToGallery(image, entry)\n } catch (caught) {\n setError(errorMessage(caught))\n }\n }\n\n /** View a gallery image in the canvas. */\n const viewGalleryEntry = async (entry: HistoryEntry): Promise<void> => {\n try {\n const restored = await historyImagesToGenerated(entry.images)\n setImages(restored)\n setError(null)\n setViewingHistoryId(null)\n setGalleryViewingId(entry.id)\n if (restored.length > 0) openPreview(restored, 0)\n } catch (caught) {\n setError(errorMessage(caught))\n }\n }\n\n /** Restore a gallery entry's parameters (and its images) into the form. */\n const restoreGalleryEntry = async (entry: HistoryEntry): Promise<void> => {\n try {\n const restored = await historyImagesToGenerated(entry.images)\n setTab(entry.mode)\n setPrompt(entry.prompt)\n setSize(normalizeSize(entry.size))\n setQuality(normalizeQuality(entry.quality))\n setDetail((DETAILS as readonly string[]).includes(entry.detail) ? entry.detail : '')\n setCount(entry.n >= 1 && entry.n <= 4 ? entry.n : 1)\n setModel(imageModels.includes(entry.model) ? entry.model : imageModels[0])\n setRefImage(null)\n setImages(restored)\n setError(null)\n setViewingHistoryId(null)\n setGalleryViewingId(null)\n } catch (caught) {\n setError(errorMessage(caught))\n }\n }\n\n /** Remove one gallery entry. */\n const deleteGalleryEntry = async (id: string): Promise<void> => {\n setGallery(gallery.filter(entry => entry.id !== id))\n if (galleryViewingId === id) setGalleryViewingId(null)\n try {\n setGallery(await api.galleryRemove(id))\n } catch {\n // Keep the optimistic local removal.\n }\n }\n\n /** Remove every gallery entry. */\n const clearGalleryAll = async (): Promise<void> => {\n setGallery([])\n setGalleryViewingId(null)\n try {\n setGallery(await api.galleryClear())\n } catch {\n // Keep the cleared local state.\n }\n }\n\n const applyGalleryTags = async (): Promise<void> => {\n const tags = galleryTagInput.split(',').map(tag => tag.trim()).filter(Boolean)\n if (tags.length === 0 || selectedGalleryIds.size === 0) return\n try {\n let next = gallery\n for (const id of selectedGalleryIds) {\n const existing = next.find(entry => entry.id === id)?.tags ?? []\n next = await api.gallerySetTags(id, [...existing, ...tags])\n }\n setGallery(next)\n setGalleryTagInput('')\n } catch (caught) { setError(errorMessage(caught)) }\n }\n\n const startEditingGalleryTags = (entry: HistoryEntry): void => {\n setEditingGalleryTagsId(entry.id)\n setGalleryTagEditInput((entry.tags ?? []).join(', '))\n }\n\n const saveGalleryTags = async (id: string): Promise<void> => {\n const tags = galleryTagEditInput.split(',').map(tag => tag.trim()).filter(Boolean)\n try {\n setGallery(await api.gallerySetTags(id, tags))\n setEditingGalleryTagsId(null)\n setGalleryTagEditInput('')\n } catch (caught) { setError(errorMessage(caught)) }\n }\n\n const toggleGallerySelection = (id: string): void => {\n setSelectedGalleryIds(previous => {\n const next = new Set(previous)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n return next\n })\n }\n\n const clearGallerySelection = (): void => {\n setSelectedGalleryIds(new Set())\n setGallerySelecting(false)\n }\n\n const exportGalleryJson = (): void => {\n const entries = gallery.filter(entry => selectedGalleryIds.has(entry.id))\n const blob = new Blob([JSON.stringify(entries, null, 2)], { type: 'application/json' })\n const url = URL.createObjectURL(blob)\n const anchor = document.createElement('a')\n anchor.href = url\n anchor.download = `dsh-imagegen-gallery-${new Date().toISOString().slice(0, 10)}.json`\n anchor.click()\n URL.revokeObjectURL(url)\n }\n\n const downloadGalleryImages = (): void => {\n gallery.filter(entry => selectedGalleryIds.has(entry.id)).forEach((entry, index) => {\n const image = entry.images[0]\n if (image === undefined) return\n const anchor = document.createElement('a')\n anchor.href = image.url\n anchor.download = `dsh-gallery-${index + 1}.${extensionOf(image.mime)}`\n anchor.click()\n })\n }\n\n const generateDisabled = submitting\n const viewingEntry = viewingHistoryId === null ? null : history.find(entry => entry.id === viewingHistoryId) ?? null\n const viewingGalleryEntry = galleryViewingId === null ? null : gallery.find(entry => entry.id === galleryViewingId) ?? null\n const previewImage = preview === null ? null : preview.images[preview.index] ?? null\n const comparisonTasks = comparison === null ? [] : comparison.taskIds.map(id => tasks.find(task => task.id === id)).filter((task): task is GenerationTask => task !== undefined)\n const comparisonResults = comparisonTasks.filter(task => task.status === 'completed' && task.result !== undefined)\n const previewFrameScale = Math.max(1, previewScale)\n const previewImageScale = previewScale / previewFrameScale\n\n const copyPreviewPrompt = async (text: string): Promise<void> => {\n try {\n if (navigator.clipboard?.writeText !== undefined) {\n await navigator.clipboard.writeText(text)\n } else {\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 const copied = document.execCommand('copy')\n textarea.remove()\n if (!copied) throw new Error('copy failed')\n }\n setPromptCopied(true)\n window.setTimeout(() => { setPromptCopied(false) }, 1800)\n } catch {\n setPromptCopied(false)\n }\n }\n\n const addPreviewToEdit = (): void => {\n if (previewImage === null || preview === null) return\n setTab('edit')\n setRefImage({\n dataUrl: srcOf(previewImage),\n name: `dsh-image-${preview.index + 1}.${extensionOf(previewImage.mime)}`,\n })\n if (prompt.trim() === '' && previewImage.revisedPrompt !== undefined) setPrompt(previewImage.revisedPrompt)\n setError(null)\n closePreview()\n }\n\n return (\n <div className={css.panel}>\n <header className={css.panelHeader}>\n <span className={css.panelHeading}>\n <h2 className={css.panelTitle}>{tt('panel.title')}</h2>\n <a\n className={css.githubLink}\n href=\"https://github.com/dickpy/dsh-imagegen\"\n target=\"_blank\"\n rel=\"noreferrer\"\n title={tt('panel.githubTip')}\n aria-label={tt('panel.githubTip')}\n >\n <svg viewBox=\"0 0 16 16\" width=\"15\" height=\"15\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8z\"/></svg>\n </a>\n </span>\n <button\n type=\"button\"\n className={css.connectionStatus}\n data-connected={connected ? 'true' : 'false'}\n aria-label={tt(connected ? 'connection.connected' : 'connection.disconnected')}\n >\n <span className={css.connectionDot} aria-hidden=\"true\" />\n {tt(connected ? 'connection.connected' : 'connection.disconnected')}\n </button>\n </header>\n\n {update !== null ? (\n <div className={css.updateBanner} data-kind={updateResult === 'success' ? 'ok' : 'warn'}>\n <span className={css.updateText}>\n {updateMessage ?? tt('update.available', { version: update.latestVersion })}\n </span>\n <span className={css.updateActions}>\n <a className={css.updateRelease} href={update.releaseUrl} target=\"_blank\" rel=\"noreferrer\">{tt('update.release')}</a>\n <Button variant=\"primary\" size=\"sm\" disabled={updating || updateMessage !== null} onClick={() => { void applyUpdate() }}>\n {updating ? tt('update.installing') : tt('update.install')}\n </Button>\n </span>\n </div>\n ) : null}\n\n <div className={css.studio}>\n {/* ---------------------------------------------------- config sidebar */}\n <aside className={css.config} data-gallery={tab === 'gallery' ? 'true' : undefined}>\n {tab === 'gallery' ? (\n <div className={css.galleryFilters}>\n <div className={css.galleryFilterHeading}>{tt('gallery.categories')}</div>\n {[\n ['all', tt('gallery.all')],\n ['text', tt('mode.text')],\n ['edit', tt('mode.edit')],\n ...galleryModels.map(value => [value, value]),\n ].map(([value, label]) => (\n <button\n key={value}\n type=\"button\"\n className={css.galleryFilter}\n data-active={galleryFilter === value ? '' : undefined}\n onClick={() => { setGalleryFilter(value) }}\n >\n <span>{label}</span>\n <span className={css.galleryFilterCount}>{gallery.filter(entry => value === 'all' || value === 'text' || value === 'edit' ? (value === 'all' ? true : entry.mode === value) : entry.model === value).length}</span>\n </button>\n ))}\n <div className={css.galleryFilterDivider} />\n <div className={css.galleryFilterHeading}>{tt('gallery.ratio')}</div>\n <div className={css.galleryRatioList}>\n {(['all', '1:1', '3:4', '4:3', '16:9'] as const).map(ratio => (\n <button key={ratio} type=\"button\" className={css.galleryRatio} data-active={galleryRatio === ratio ? '' : undefined} onClick={() => { setGalleryRatio(ratio) }}>\n {ratio === 'all' ? tt('gallery.all') : ratio}\n </button>\n ))}\n </div>\n {galleryTagOptions.length > 0 ? (\n <>\n <div className={css.galleryFilterDivider} />\n <div className={css.galleryFilterHeading}>{tt('gallery.tags')}</div>\n <div className={css.galleryTagFilterList}>\n {galleryTagOptions.map(tag => (\n <button key={tag} type=\"button\" className={css.galleryTagFilter} data-active={galleryTagFilter === tag ? '' : undefined} onClick={() => { setGalleryTagFilter(previous => previous === tag ? null : tag) }}>\n <span>{tag}</span>\n <span>{gallery.filter(entry => (entry.tags ?? []).includes(tag)).length}</span>\n </button>\n ))}\n </div>\n </>\n ) : null}\n <div className={css.galleryFilterNote}>{tt('gallery.filterHint')}</div>\n </div>\n ) : null}\n <div className={css.configScroll}>\n {/* mode / gallery tabs */}\n <section className={css.card}>\n <div className={css.modeRow} role=\"tablist\" aria-label={tt('panel.title')}>\n <Pill active={tab === 'text'} onClick={() => { setTab('text') }} className={css.modePill}>{tt('mode.text')}</Pill>\n <Pill active={tab === 'edit'} onClick={() => { setTab('edit') }} className={css.modePill}>{tt('mode.edit')}</Pill>\n <Pill active={tab === 'gallery'} onClick={() => { setTab('gallery') }} className={css.modePill}>{tt('gallery.title')}</Pill>\n </div>\n </section>\n\n {/* reference image (edit mode) */}\n {tab === 'edit' ? (\n <section className={css.card}>\n {refImage === null\n ? (\n <button\n type=\"button\"\n className={css.uploadBox}\n onClick={() => { fileInput.current?.click() }}\n onDragOver={(event) => { event.preventDefault() }}\n onDrop={(event) => {\n event.preventDefault()\n acceptFile(event.dataTransfer.files?.[0])\n }}\n >\n <span className={css.uploadIcon}>\n <svg viewBox=\"0 0 16 16\" width=\"18\" height=\"18\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.3\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><path d=\"M8 10.5V3\"/><path d=\"M5 5.5l3-3 3 3\"/><path d=\"M2.5 9v3.5h11V9\"/></svg>\n </span>\n <span>{tt('edit.upload')}</span>\n <span className={css.uploadHint}>{tt('edit.uploadHint')}</span>\n </button>\n )\n : (\n <div className={css.reference}>\n <img className={css.referenceImage} src={refImage.dataUrl} alt={refImage.name} />\n <div className={css.referenceActions}>\n <Button variant=\"outline\" size=\"sm\" onClick={() => { fileInput.current?.click() }}>\n {tt('edit.change')}\n </Button>\n <Button variant=\"outline\" size=\"sm\" onClick={() => { setRefImage(null) }}>\n {tt('edit.remove')}\n </Button>\n </div>\n </div>\n )}\n <input\n ref={fileInput}\n type=\"file\"\n accept=\"image/png,image/jpeg,image/webp,image/gif\"\n className={css.hiddenFile}\n onChange={(event) => {\n acceptFile(event.target.files?.[0])\n event.target.value = ''\n }}\n />\n </section>\n ) : null}\n\n {/* prompt */}\n <section className={css.card}>\n <textarea\n className={css.prompt}\n value={prompt}\n placeholder={tt('prompt.placeholder')}\n onChange={(event) => { setPrompt(event.target.value) }}\n />\n <div className={css.promptFooter}>\n <button\n type=\"button\"\n className={css.templatesButton}\n title={tt('templates.title')}\n onClick={() => { setLibraryOpen(true) }}\n >\n <svg viewBox=\"0 0 16 16\" width=\"12\" height=\"12\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.4\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><path d=\"M2.5 3.5h11M2.5 8h11M2.5 12.5h7\"/></svg>\n {tt('templates.open')}\n </button>\n <button\n type=\"button\"\n className={css.enhanceButton}\n disabled={prompt.trim() === '' || enhancing}\n title={tt('prompt.enhanceHint')}\n onClick={() => { void enhanceCurrentPrompt() }}\n >\n {enhancing ? tt('prompt.enhancing') : tt('prompt.enhance')}\n </button>\n <span className={css.promptCount}>{tt('prompt.count', { count: prompt.length })}</span>\n </div>\n </section>\n\n {/* parameters */}\n <section className={css.card}>\n <div className={css.paramGroup}>\n <span className={css.paramLabel}>{tt('params.size')}</span>\n <div className={css.optionGrid}>\n {SIZES.map(option => (\n <Pill\n key={option}\n active={size === option}\n onClick={() => { setSize(option) }}\n className={css.optionPill}\n >\n {tt(SIZE_KEYS[option] ?? 'size.auto')}\n </Pill>\n ))}\n </div>\n </div>\n <div className={css.paramGroup}>\n <span className={css.paramLabel}>{tt('params.quality')}</span>\n <div className={css.optionRow}>\n {QUALITIES.map(option => (\n <Pill\n key={option}\n active={quality === option}\n onClick={() => { setQuality(option) }}\n className={css.optionPill}\n >\n {tt(`quality.${option}` as const)}\n </Pill>\n ))}\n </div>\n </div>\n <div className={css.paramGroup}>\n <span className={css.paramLabel}>{tt('params.count')}</span>\n <div className={css.optionRow}>\n {[1, 2, 3, 4].map(option => (\n <Pill\n key={option}\n active={count === option}\n onClick={() => { setCount(option) }}\n className={css.optionPill}\n >\n {tt(`count.${option === 1 ? 'one' : option === 2 ? 'two' : option === 3 ? 'three' : 'four'}` as const)}\n </Pill>\n ))}\n </div>\n </div>\n <div className={css.paramGroup}>\n <span className={css.paramLabel}>{tt('params.detail')}</span>\n <div className={css.optionRow}>\n {DETAILS.map(option => (\n <Pill\n key={option === '' ? 'auto' : option}\n active={detail === option}\n onClick={() => { setDetail(option) }}\n className={css.optionPill}\n >\n {tt(option === '' ? 'detail.auto' : option === 'standard' ? 'detail.standard' : 'detail.high')}\n </Pill>\n ))}\n </div>\n <span className={css.paramHint}>{tt('detail.hint')}</span>\n </div>\n </section>\n </div>\n\n {/* footer: model + generate — a fixed sibling of the scroll area, so\n it never overlaps the cards scrolling above it. */}\n <section className={css.footer}>\n <label className={css.modelWrap}>\n <span className={css.modelLabel}>{tt('model.label')}</span>\n <span ref={modelMenuRef} className={css.modelMenu} data-open={modelOpen ? 'true' : 'false'}>\n <button\n type=\"button\"\n className={css.modelSelect}\n disabled={submitting}\n aria-haspopup=\"listbox\"\n aria-expanded={modelOpen}\n onClick={() => { setModelOpen(open => !open) }}\n >\n <span>{model}</span>\n <svg viewBox=\"0 0 16 16\" width=\"12\" height=\"12\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><path d=\"M8 10.5L4 6h8z\"/></svg>\n </button>\n {modelOpen ? (\n <div className={css.modelMenuList} role=\"listbox\" aria-label={tt('model.label')}>\n {imageModels.map(option => (\n <button\n key={option}\n type=\"button\"\n role=\"option\"\n aria-selected={model === option}\n className={css.modelMenuItem}\n data-selected={model === option ? '' : undefined}\n onClick={() => { setModel(option); setModelOpen(false) }}\n >\n {option}\n </button>\n ))}\n </div>\n ) : null}\n </span>\n </label>\n <div className={css.compareControl}>\n <label className={css.compareToggle}>\n <input type=\"checkbox\" checked={compareEnabled} onChange={event => { setCompareEnabled(event.target.checked) }} />\n <span>{tt('compare.enable')}</span>\n </label>\n {compareEnabled ? (\n <div className={css.compareModelChoices} role=\"group\" aria-label={tt('compare.models')}>\n {imageModels.map(option => (\n <label key={option}>\n <input type=\"checkbox\" checked={compareModels.includes(option)} onChange={() => { setCompareModels(previous => previous.includes(option) ? previous.filter(value => value !== option) : [...previous, option]) }} />\n <span>{option}</span>\n </label>\n ))}\n </div>\n ) : null}\n </div>\n <Button\n variant=\"primary\"\n size=\"md\"\n className={css.generateButton}\n disabled={generateDisabled}\n onClick={() => { void handleGenerate() }}\n >\n {generating ? (\n <span className={css.generateInner}>\n <span className={css.spinner} />\n {tt('generating')}\n </span>\n ) : tt('generate')}\n </Button>\n </section>\n </aside>\n\n {/* --------------------------------------------------------- canvas */}\n <section className={css.canvas} data-gallery={tab === 'gallery' ? 'true' : undefined}>\n {tab === 'gallery' ? (\n <div className={css.galleryWorkspace}>\n <header className={css.galleryToolbar}>\n <div>\n <h3 className={css.galleryHeading}>{tt('gallery.all')}</h3>\n <span className={css.galleryCount}>{tt('gallery.count', { count: filteredGallery.length })}</span>\n </div>\n <div className={css.galleryToolbarActions}>\n <input className={css.gallerySearch} value={galleryQuery} onChange={event => { setGalleryQuery(event.target.value) }} placeholder={tt('gallery.search')} aria-label={tt('gallery.search')} />\n <button type=\"button\" className={css.gallerySelectMode} data-active={gallerySelecting ? '' : undefined} aria-pressed={gallerySelecting} onClick={() => { setGallerySelecting(previous => !previous) }}>\n {gallerySelecting ? tt('gallery.selectionDone') : tt('gallery.select')}\n </button>\n <div className={css.galleryViewToggle} role=\"group\" aria-label={tt('gallery.viewMode')}>\n <button type=\"button\" data-active={galleryView === 'masonry' ? '' : undefined} onClick={() => { setGalleryView('masonry') }} title={tt('gallery.masonry')}>\n <span aria-hidden=\"true\">▦</span> {tt('gallery.masonry')}\n </button>\n <button type=\"button\" data-active={galleryView === 'grid' ? '' : undefined} onClick={() => { setGalleryView('grid') }} title={tt('gallery.grid')}>\n <span aria-hidden=\"true\">▤</span> {tt('gallery.grid')}\n </button>\n </div>\n <select className={css.gallerySort} value={gallerySort} onChange={event => { setGallerySort(event.target.value as 'newest' | 'oldest') }} aria-label={tt('gallery.sort')}>\n <option value=\"newest\">{tt('gallery.newest')}</option>\n <option value=\"oldest\">{tt('gallery.oldest')}</option>\n </select>\n {gallery.length > 0 ? <button type=\"button\" className={css.galleryClear} onClick={() => { void clearGalleryAll() }}>{tt('gallery.clear')}</button> : null}\n </div>\n </header>\n {selectedGalleryIds.size > 0 ? (\n <section className={css.gallerySelectionBar} aria-label={tt('gallery.selected', { count: selectedGalleryIds.size })}>\n <strong>{tt('gallery.selected', { count: selectedGalleryIds.size })}</strong>\n <input className={css.galleryTagInput} value={galleryTagInput} onChange={event => { setGalleryTagInput(event.target.value) }} placeholder={tt('gallery.tagsPlaceholder')} aria-label={tt('gallery.tagsPlaceholder')} />\n <button type=\"button\" className={css.galleryBulkButton} disabled={galleryTagInput.trim() === ''} onClick={() => { void applyGalleryTags() }}>{tt('gallery.tagsApply')}</button>\n <button type=\"button\" className={css.galleryBulkButton} onClick={downloadGalleryImages}>{tt('gallery.downloadSelected')}</button>\n <button type=\"button\" className={css.galleryBulkButton} onClick={exportGalleryJson}>{tt('gallery.exportJson')}</button>\n <button type=\"button\" className={css.gallerySelectionClear} onClick={clearGallerySelection}>{tt('gallery.selectionClear')}</button>\n </section>\n ) : null}\n {filteredGallery.length === 0 ? (\n <div className={css.historyEmpty}>{tt('gallery.empty')}</div>\n ) : (\n <div className={css.galleryMasonry} data-view={galleryView}>\n {filteredGallery.map(entry => {\n const image = entry.images[0]\n if (image === undefined) return null\n return (\n <article key={entry.id} className={css.galleryCard} data-selected={selectedGalleryIds.has(entry.id) ? '' : undefined}>\n <label className={css.gallerySelect} title={tt('gallery.select')}>\n <input type=\"checkbox\" checked={selectedGalleryIds.has(entry.id)} onChange={() => { setGallerySelecting(true); toggleGallerySelection(entry.id) }} />\n </label>\n <button type=\"button\" className={css.galleryImageButton} data-selecting={gallerySelecting ? '' : undefined} onClick={() => { if (gallerySelecting) toggleGallerySelection(entry.id); else void viewGalleryEntry(entry) }} title={gallerySelecting ? tt('gallery.select') : tt('preview.open')}>\n <img className={css.galleryImage} src={image.url} alt={entry.prompt} />\n <span className={css.galleryBadge}>{entry.mode === 'edit' ? tt('mode.edit') : tt('mode.text')}</span>\n </button>\n <div className={css.galleryCardFooter}>\n <span className={css.galleryAvatar}>{entry.model.toLowerCase().startsWith('nanobanana') ? 'N' : entry.model.toLowerCase().startsWith('seedream') ? 'S' : entry.model.startsWith('grok') ? 'G' : 'D'}</span>\n <span className={css.galleryCardInfo}>\n <strong>{entry.prompt || tt('gallery.untitled')}</strong>\n <small>{entry.model} · {normalizeSize(entry.size)} · {formatTime(entry.createdAt)}</small>\n <span className={css.galleryTags}>\n {(entry.tags ?? []).map(tag => <button key={tag} type=\"button\" onClick={() => { setGalleryTagFilter(tag) }}>{tag}</button>)}\n <button type=\"button\" className={css.galleryTagEdit} onClick={() => { startEditingGalleryTags(entry) }} title={tt('gallery.editTags')}>{tt('gallery.tagsEditShort')}</button>\n </span>\n </span>\n <button type=\"button\" className={css.galleryRemove} onClick={() => { void deleteGalleryEntry(entry.id) }} title={tt('gallery.delete')}>×</button>\n </div>\n {editingGalleryTagsId === entry.id ? (\n <form className={css.galleryTagEditor} onSubmit={event => { event.preventDefault(); void saveGalleryTags(entry.id) }}>\n <input value={galleryTagEditInput} onChange={event => { setGalleryTagEditInput(event.target.value) }} placeholder={tt('gallery.tagsPlaceholder')} aria-label={tt('gallery.tagsPlaceholder')} autoFocus />\n <button type=\"submit\">{tt('gallery.tagsSave')}</button>\n <button type=\"button\" onClick={() => { setEditingGalleryTagsId(null); setGalleryTagEditInput('') }}>{tt('gallery.tagsCancel')}</button>\n </form>\n ) : null}\n </article>\n )\n })}\n </div>\n )}\n </div>\n ) : null}\n {tab !== 'gallery' && tasks.length > 0 ? (\n <section className={css.taskTray} data-open={taskTrayOpen ? 'true' : 'false'} aria-label={tt('tasks.title')}>\n <header className={css.taskTrayHeader}>\n <button type=\"button\" className={css.taskTrayToggle} aria-expanded={taskTrayOpen} onClick={() => { setTaskTrayOpen(open => !open) }}>\n <span>{tt('tasks.title')}</span>\n <span className={css.taskTrayCount}>{activeTasks.length}</span>\n <span className={css.taskTrayChevron} aria-hidden=\"true\">{taskTrayOpen ? '⌃' : '⌄'}</span>\n </button>\n {taskTrayOpen ? <button type=\"button\" className={css.taskTrayClose} aria-label={tt('preview.close')} onClick={() => { setTaskTrayOpen(false) }}>×</button> : null}\n </header>\n <div className={css.taskRows}>\n {tasks.slice(0, 5).map(task => (\n <div key={task.id} className={css.taskRow} data-status={task.status}>\n <span className={css.taskStatus}>{tt(`tasks.${task.status}` as never)}</span>\n <span className={css.taskPrompt}>{task.request.prompt}</span>\n {(task.status === 'queued' || task.status === 'running') ? <button type=\"button\" onClick={() => { void api.taskCancel(task.id) }}>{tt('tasks.cancel')}</button> : null}\n {task.status === 'failed' || task.status === 'cancelled' ? <button type=\"button\" onClick={() => { void api.taskRetry(task.id) }}>{tt('tasks.retry')}</button> : null}\n </div>\n ))}\n </div>\n </section>\n ) : null}\n {tab !== 'gallery' && comparison !== null ? (\n <section className={css.comparisonBoard} aria-label={tt('compare.title')}>\n <header><div><strong>{tt('compare.title')}</strong><span>{comparisonResults.length} / {comparisonTasks.length}</span></div><button type=\"button\" disabled={comparisonResults.length === 0} onClick={() => { setComparisonFullscreen(true) }}>{tt('compare.fullscreen')}</button></header>\n <div className={css.comparisonGrid}>\n {comparisonTasks.map(task => (\n <article key={task.id}>\n <strong>{task.request.model}</strong>\n {task.result?.images[0] !== undefined ? <img src={srcOf(task.result.images[0])} alt={task.request.model} /> : <span>{tt(`tasks.${task.status}` as never)}</span>}\n </article>\n ))}\n </div>\n </section>\n ) : null}\n {generating ? (\n <div className={css.canvasState} data-generation-state={activeTask?.status ?? 'submitting'} role=\"status\">\n <span className={css.bigSpinner} />\n <span className={css.canvasStateTitle}>\n {submitting && activeTask === undefined\n ? tt('canvas.submitting')\n : activeTask?.status === 'queued'\n ? tt('canvas.queued')\n : tt('canvas.generating')}\n </span>\n <span className={css.canvasStateHint}>\n {activeTask?.status === 'queued'\n ? tt('canvas.queueHint', { count: activeTasks.length })\n : tt('canvas.elapsed', { seconds: elapsed })}\n </span>\n </div>\n ) : null}\n\n {!generating && error !== null ? (\n <div className={css.canvasError} role=\"alert\">{tt('canvas.error', { error })}</div>\n ) : null}\n\n {!generating && !error && images.length === 0 ? (\n <div className={css.canvasState}>\n <span className={css.canvasEmptyIcon}>\n <svg viewBox=\"0 0 24 24\" width=\"34\" height=\"34\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"3\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><path d=\"M21 15l-5-5L5 21\"/></svg>\n </span>\n <span className={css.canvasStateTitle}>{tt('canvas.emptyTitle')}</span>\n <span className={css.canvasStateHint}>{tt('canvas.emptyHint')}</span>\n </div>\n ) : null}\n\n {!generating && images.length > 0 ? (\n <div className={css.canvasBody}>\n <div className={css.canvasMeta}>\n <span>{tt('canvas.images', { count: images.length })}</span>\n {viewingEntry !== null || viewingGalleryEntry !== null ? (\n <span className={css.canvasHistoryTag}>\n {viewingEntry !== null\n ? tt('history.viewing', { time: formatTime(viewingEntry.createdAt) })\n : tt('gallery.viewing', { time: formatTime(viewingGalleryEntry!.createdAt) })}\n </span>\n ) : null}\n </div>\n <div className={css.grid} data-count={images.length}>\n {images.map((image, index) => (\n <figure\n key={index}\n className={css.imageCard}\n role=\"button\"\n tabIndex={0}\n title={tt('preview.open')}\n onClick={() => { openPreview(images, index) }}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n openPreview(images, index)\n }\n }}\n >\n <img\n className={css.image}\n src={srcOf(image)}\n alt={image.revisedPrompt ?? `${tt('panel.title')} ${index + 1}`}\n />\n {image.revisedPrompt !== undefined ? (\n <figcaption className={css.imageCaption} title={image.revisedPrompt}>\n {tt('revisedPrompt', { prompt: image.revisedPrompt })}\n </figcaption>\n ) : null}\n <span className={css.zoomHint}>\n <svg viewBox=\"0 0 16 16\" width=\"13\" height=\"13\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.4\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><circle cx=\"7\" cy=\"7\" r=\"4\"/><path d=\"M13 13l-3.2-3.2\"/><path d=\"M7 5.4v3.2M5.4 7h3.2\"/></svg>\n {tt('preview.open')}\n </span>\n <button\n type=\"button\"\n className={css.galleryAdd}\n title={tt('gallery.add')}\n disabled={galleryAdding}\n onClick={(event) => { event.stopPropagation(); void addToGallery(image) }}\n >\n <svg viewBox=\"0 0 16 16\" width=\"12\" height=\"12\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><rect x=\"2.5\" y=\"3\" width=\"11\" height=\"10\" rx=\"1.5\"/><path d=\"M8 5.8v4.4M5.8 8h4.4\"/></svg>\n {tt('gallery.add')}\n </button>\n <a\n className={css.download}\n href={srcOf(image)}\n download={`dsh-image-${index + 1}.${extensionOf(image.mime)}`}\n onClick={(event) => { event.stopPropagation() }}\n >\n {tt('download')}\n </a>\n </figure>\n ))}\n </div>\n </div>\n ) : null}\n </section>\n\n {/* ------------------------ right column: gallery (tab) or history */}\n {tab === 'gallery' ? (\n <aside className={css.history}>\n <header className={css.historyHeader}>\n <span className={css.historyTitle}>{tt('gallery.title')}</span>\n {gallery.length > 0 ? (\n <button type=\"button\" className={css.historyClear} onClick={() => { void clearGalleryAll() }}>\n {tt('gallery.clear')}\n </button>\n ) : null}\n </header>\n\n {gallery.length === 0 ? (\n <div className={css.historyEmpty}>{tt('gallery.empty')}</div>\n ) : (\n <div className={css.historyList}>\n {gallery.map(entry => (\n <div\n key={entry.id}\n className={css.historyItem}\n data-active={entry.id === galleryViewingId ? '' : undefined}\n >\n <button\n type=\"button\"\n className={css.historyMain}\n onClick={() => { void viewGalleryEntry(entry) }}\n >\n {entry.images.length > 0 ? (\n <img className={css.historyThumb} src={entry.images[0]!.url} alt=\"\" />\n ) : (\n <span className={css.historyThumbPlaceholder} />\n )}\n <span className={css.historyInfo}>\n <span className={css.historyPrompt}>{entry.prompt}</span>\n <span className={css.historyMeta}>\n {tt(`mode.${entry.mode === 'edit' ? 'edit' : 'text'}` as const)}\n {' · '}{formatTime(entry.createdAt)}\n </span>\n </span>\n </button>\n <span className={css.historyActions}>\n <button type=\"button\" className={css.historyAction} onClick={() => { void restoreGalleryEntry(entry) }}>\n {tt('history.restore')}\n </button>\n <button type=\"button\" className={css.historyAction} data-danger onClick={() => { void deleteGalleryEntry(entry.id) }}>\n {tt('gallery.delete')}\n </button>\n </span>\n </div>\n ))}\n </div>\n )}\n </aside>\n ) : (\n <aside className={css.history}>\n <header className={css.historyHeader}>\n <span className={css.historyTitle}>{tt('history.title')}</span>\n {history.length > 0 ? (\n <button type=\"button\" className={css.historyClear} onClick={() => { void clearHistory() }}>\n {tt('history.clear')}\n </button>\n ) : null}\n </header>\n\n <div className={css.historyFilters}>\n <input className={css.historySearch} value={historyQuery} onChange={event => { setHistoryQuery(event.target.value) }} placeholder={tt('history.search')} aria-label={tt('history.search')} />\n <select value={historyModelFilter} onChange={event => { setHistoryModelFilter(event.target.value) }} aria-label={tt('history.model')}>\n <option value=\"all\">{tt('history.allModels')}</option>\n {[...new Set(history.map(entry => entry.model))].map(option => <option key={option} value={option}>{option}</option>)}\n </select>\n <select value={historyRatioFilter} onChange={event => { setHistoryRatioFilter(event.target.value) }} aria-label={tt('history.ratio')}>\n <option value=\"all\">{tt('history.allRatios')}</option>\n {[...new Set(history.map(entry => normalizeSize(entry.size)))].map(option => <option key={option} value={option}>{option}</option>)}\n </select>\n </div>\n\n {filteredHistory.length === 0 ? (\n <div className={css.historyEmpty}>{tt('history.empty')}</div>\n ) : (\n <div className={css.historyList}>\n {filteredHistory.map(entry => (\n <div\n key={entry.id}\n className={css.historyItem}\n data-active={entry.id === viewingHistoryId ? '' : undefined}\n >\n <button\n type=\"button\"\n className={css.historyMain}\n onClick={() => { void viewHistoryEntry(entry) }}\n >\n {entry.images.length > 0 ? (\n <img className={css.historyThumb} src={entry.images[0]!.url} alt=\"\" />\n ) : (\n <span className={css.historyThumbPlaceholder} />\n )}\n <span className={css.historyInfo}>\n <span className={css.historyPrompt}>{entry.prompt}</span>\n <span className={css.historyMeta}>\n {tt(`mode.${entry.mode === 'edit' ? 'edit' : 'text'}` as const)}\n {' · '}{formatTime(entry.createdAt)}\n {' · '}{entry.images.length} {tt('history.images')}\n </span>\n </span>\n </button>\n <span className={css.historyActions}>\n {entry.images.length > 0 ? (\n <button\n type=\"button\"\n className={css.historyAction}\n disabled={galleryAdding}\n title={tt('gallery.add')}\n onClick={() => { void addHistoryEntryToGallery(entry) }}\n >\n {tt('gallery.add')}\n </button>\n ) : null}\n <button type=\"button\" className={css.historyAction} onClick={() => { void restoreHistoryEntry(entry) }}>\n {tt('history.restore')}\n </button>\n <button type=\"button\" className={css.historyAction} data-danger onClick={() => { void deleteHistoryEntry(entry.id) }}>\n {tt('history.delete')}\n </button>\n </span>\n </div>\n ))}\n </div>\n )}\n </aside>\n )}\n </div>\n\n {/* ------------------------------------------------ template library */}\n {libraryOpen ? (\n <TemplateLibrary\n api={api}\n onClose={() => { setLibraryOpen(false) }}\n onUse={(text) => {\n setTab('text')\n setPrompt(text)\n setError(null)\n setLibraryOpen(false)\n }}\n />\n ) : null}\n\n {configGuide !== null ? (\n <div className={css.configGuide} role=\"dialog\" aria-modal=\"true\" aria-label={tt(`config.${configGuide}Title` as never)}>\n <div className={css.configGuideBody}>\n <strong>{tt(`config.${configGuide}Title` as never)}</strong>\n <span>{tt(`config.${configGuide}Hint` as never)}</span>\n <button type=\"button\" onClick={() => { setConfigGuide(null) }}>{tt('preview.close')}</button>\n </div>\n </div>\n ) : null}\n\n {comparisonFullscreen && comparison !== null ? createPortal(\n <div className={css.comparisonFullscreen} role=\"dialog\" aria-modal=\"true\" aria-label={tt('compare.title')} onClick={() => { setComparisonFullscreen(false) }}>\n <button type=\"button\" className={css.lightboxClose} aria-label={tt('preview.close')} onClick={() => { setComparisonFullscreen(false) }}>×</button>\n <div className={css.comparisonFullscreenGrid} onClick={event => { event.stopPropagation() }}>\n {comparisonResults.map(task => (\n <figure key={task.id}><figcaption>{task.request.model}</figcaption>{task.result!.images.map((image, index) => <img key={index} src={srcOf(image)} alt={task.request.model} />)}</figure>\n ))}\n </div>\n </div>, document.body) : null}\n\n {/* -------------------------------------------------- preview overlay */}\n {preview !== null && previewImage !== null\n ? createPortal(\n <div\n className={css.lightbox}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={tt('preview.title')}\n onClick={closePreview}\n >\n <button type=\"button\" className={css.lightboxClose} aria-label={tt('preview.close')} title={tt('preview.close')} onClick={closePreview}>\n <svg viewBox=\"0 0 16 16\" width=\"18\" height=\"18\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" aria-hidden=\"true\"><path d=\"M4 4l8 8M12 4l-8 8\"/></svg>\n </button>\n {preview.images.length > 1 ? (\n <>\n <button type=\"button\" className={css.lightboxNav} data-dir=\"prev\" aria-label={tt('preview.prev')} onClick={(event) => { event.stopPropagation(); stepPreview(-1) }}>\n <svg viewBox=\"0 0 16 16\" width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><path d=\"M10 3l-5 5 5 5\"/></svg>\n </button>\n <button type=\"button\" className={css.lightboxNav} data-dir=\"next\" aria-label={tt('preview.next')} onClick={(event) => { event.stopPropagation(); stepPreview(1) }}>\n <svg viewBox=\"0 0 16 16\" width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 3l5 5-5 5\"/></svg>\n </button>\n </>\n ) : null}\n <figure className={css.lightboxFigure} onClick={(event) => { event.stopPropagation() }}>\n <div\n ref={previewStage}\n className={css.lightboxStage}\n onWheel={(event) => {\n event.preventDefault()\n setPreviewScale(current => clampPreviewScale(current + (event.deltaY < 0 ? PREVIEW_SCALE_STEP : -PREVIEW_SCALE_STEP)))\n }}\n >\n <div\n className={css.lightboxScaleFrame}\n style={{ width: `${previewFrameScale * 100}%`, height: `${previewFrameScale * 100}%` }}\n >\n <img\n className={css.lightboxImage}\n style={{ width: `${previewImageScale * 100}%`, height: `${previewImageScale * 100}%` }}\n src={srcOf(previewImage)}\n alt={previewImage.revisedPrompt ?? tt('preview.title')}\n />\n </div>\n </div>\n <div className={css.lightboxTools} role=\"group\" aria-label={tt('preview.zoomControls')}>\n <button type=\"button\" className={css.lightboxTool} aria-label={tt('preview.zoomOut')} title={tt('preview.zoomOut')} onClick={() => { setPreviewScale(current => clampPreviewScale(current - PREVIEW_SCALE_STEP)) }}>\n <svg viewBox=\"0 0 16 16\" width=\"17\" height=\"17\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.7\" strokeLinecap=\"round\" aria-hidden=\"true\"><circle cx=\"7\" cy=\"7\" r=\"4.2\"/><path d=\"M4.8 7h4.4M13 13l-2.8-2.8\"/></svg>\n </button>\n <button type=\"button\" className={css.lightboxZoomLevel} aria-label={tt('preview.zoomReset')} title={tt('preview.zoomReset')} onClick={() => { setPreviewScale(1) }}>\n {tt('preview.zoomLevel', { percent: Math.round(previewScale * 100) })}\n </button>\n <button type=\"button\" className={css.lightboxTool} aria-label={tt('preview.zoomIn')} title={tt('preview.zoomIn')} onClick={() => { setPreviewScale(current => clampPreviewScale(current + PREVIEW_SCALE_STEP)) }}>\n <svg viewBox=\"0 0 16 16\" width=\"17\" height=\"17\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.7\" strokeLinecap=\"round\" aria-hidden=\"true\"><circle cx=\"7\" cy=\"7\" r=\"4.2\"/><path d=\"M7 4.8v4.4M4.8 7h4.4M13 13l-2.8-2.8\"/></svg>\n </button>\n </div>\n {previewImage.revisedPrompt !== undefined ? (\n <div className={css.lightboxCaptionRow}>\n <figcaption className={css.lightboxCaption} title={previewImage.revisedPrompt}>\n {tt('revisedPrompt', { prompt: previewImage.revisedPrompt })}\n </figcaption>\n <button type=\"button\" className={css.lightboxCopy} aria-label={tt(promptCopied ? 'preview.copied' : 'preview.copyPrompt')} title={tt(promptCopied ? 'preview.copied' : 'preview.copyPrompt')} onClick={() => { void copyPreviewPrompt(previewImage.revisedPrompt!) }}>\n {promptCopied ? (\n <svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 8l3 3 7-7\"/></svg>\n ) : (\n <svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><rect x=\"5\" y=\"5\" width=\"7\" height=\"8\" rx=\"1\"/><path d=\"M3 10V3.8c0-.44.36-.8.8-.8H9\"/></svg>\n )}\n <span>{tt(promptCopied ? 'preview.copied' : 'preview.copyPrompt')}</span>\n </button>\n </div>\n ) : null}\n <div className={css.lightboxMeta}>\n <span className={css.lightboxIndex}>{tt('preview.index', { index: preview.index + 1, total: preview.images.length })}</span>\n <span className={css.lightboxActions}>\n <button type=\"button\" className={css.lightboxEdit} disabled={galleryAdding} onClick={() => { void addToGallery(previewImage) }}>\n {tt('gallery.add')}\n </button>\n <button type=\"button\" className={css.lightboxEdit} onClick={addPreviewToEdit}>\n {tt('preview.addToEdit')}\n </button>\n <a\n className={css.lightboxDownload}\n href={srcOf(previewImage)}\n download={`dsh-image-${preview.index + 1}.${extensionOf(previewImage.mime)}`}\n >\n {tt('download')}\n </a>\n </span>\n </div>\n </figure>\n </div>,\n document.body,\n )\n : null}\n\n {/* ------------------------------------------------- gallery toast */}\n {galleryMessage !== null ? (\n <div className={css.galleryToast} role=\"status\">\n <svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\"><rect x=\"2.5\" y=\"3\" width=\"11\" height=\"10\" rx=\"1.5\"/><path d=\"M8 5.8v4.4M5.8 8h4.4\"/></svg>\n {galleryMessage}\n </div>\n ) : null}\n </div>\n )\n}\n\n/** File extension for a MIME type (download filenames). */\nfunction extensionOf(mime: string): string {\n switch (mime.split(';')[0]!.trim()) {\n case 'image/jpeg': return 'jpg'\n case 'image/webp': return 'webp'\n case 'image/gif': return 'gif'\n default: return 'png'\n }\n}\n","/**\n * Panel view mounting.\n *\n * The `conversation` slot is single-occupant (ui-conversation) and external\n * plugins cannot declare slots, so the panel takes over the center column at\n * the DOM level: a container is appended inside the conversation grid item\n * (an extra trailing child React never manages), and a stylesheet rule hides\n * the conversation content while the panel is active. Toggling is a data\n * attribute on <html> — no React involvement, so the conversation subtree\n * underneath stays mounted and stateful.\n *\n * Shell compatibility: the center column is `[data-pane=\"conversation\"]` on\n * legacy shells and `[class*=\"centerCol\"]` on the rc.6+ AppFrame layout (the\n * same dual selector the dsh-ssh / task-board panels use); both are queried\n * and both get the `position: relative` base in panel.module.css.\n */\n\nimport { createRoot, type Root } from 'react-dom/client'\nimport type { ImageGenApi } from './api.ts'\nimport type { ImageGenController } from './controller.ts'\nimport { ImageGenPanel } from './ImageGenPanel.tsx'\nimport type { ImageGenScope } from './settings-scope.ts'\nimport css from './panel.module.css'\n\n/** The injected panel container (kept in the DOM, hidden when inactive). */\nexport const PANEL_VIEW_SELECTOR = '[data-dsh-imagegen-view]'\n\nconst CONVERSATION_COLUMN_SELECTOR = '[data-pane=\"conversation\"], [class*=\"centerCol\"]'\nconst ACTIVE_ATTR = 'data-dsh-imagegen-active'\n/** Sibling panels' activation attributes, removed when this panel opens. */\nconst OTHER_ACTIVE_ATTRS = ['data-dsh-taskboard-active', 'data-dsh-ssh-active']\n/** Cross-plugin activation event; detail is the activating panel name. */\nconst ACTIVATE_EVENT = 'dsh-panel-activate'\nconst PANEL_NAME = 'imagegen'\n\n/** Find the center column, or undefined while the frame is not mounted. */\nfunction conversationColumn(): HTMLElement | undefined {\n return document.querySelector<HTMLElement>(CONVERSATION_COLUMN_SELECTOR) ?? undefined\n}\n\n/**\n * Mount the panel React tree into the center column and bind its visibility\n * to the controller's panelOpen state.\n * @param controller - the panel controller driving the view.\n * @param api - the image-generation API client the panel operates through.\n * @param scope - the settings scope (config status banner).\n * @returns disposer unmounting the tree and restoring the column.\n */\nexport function mountPanel(\n controller: ImageGenController,\n api: ImageGenApi,\n scope: ImageGenScope,\n): () => void {\n let root: Root | undefined\n let container: HTMLDivElement | undefined\n\n const ensure = (): void => {\n if (container !== undefined) {\n if (container.isConnected) return\n // The conversation pane was replaced; drop the stale tree and remount.\n root?.unmount()\n root = undefined\n container.remove()\n container = undefined\n }\n const column = conversationColumn()\n if (column === undefined) return\n container = document.createElement('div')\n container.dataset.dshImagegenView = ''\n container.className = css.view\n column.appendChild(container)\n root = createRoot(container)\n root.render(<ImageGenPanel api={api} scope={scope} />)\n }\n\n // The frame mounts after boot settlement; watch for the column's arrival.\n const waitObserver = new MutationObserver(() => { ensure() })\n waitObserver.observe(document.body, { childList: true, subtree: true })\n\n const applyActive = (): void => {\n if (controller.getSnapshot().panelOpen) {\n // Single-occupant center column: opening this panel must evict sibling\n // panels (task board / ssh), both their html attributes and their\n // controller states, otherwise the visibility rules fight.\n for (const attr of OTHER_ACTIVE_ATTRS) document.documentElement.removeAttribute(attr)\n document.documentElement.setAttribute(ACTIVE_ATTR, '')\n document.dispatchEvent(new CustomEvent(ACTIVATE_EVENT, { detail: PANEL_NAME }))\n } else {\n document.documentElement.removeAttribute(ACTIVE_ATTR)\n }\n }\n const onOtherActivate = (event: Event): void => {\n const detail = (event as CustomEvent).detail\n if ((detail === 'ssh' || detail === 'taskboard') && controller.getSnapshot().panelOpen) {\n controller.close()\n }\n }\n // Jump out on sidebar context clicks: clicking a session/workspace row\n // hands the center column back to the conversation. Capture phase.\n const SIDEBAR_ROW_SELECTOR = '[class*=\"sessionRow\"], [class*=\"projectRow\"], [class*=\"searchResultRow\"], [class*=\"searchResultWorkspace\"], [class*=\"newSession\"]'\n const onClickSidebarRow = (event: MouseEvent): void => {\n if (!controller.getSnapshot().panelOpen) return\n const target = event.target as HTMLElement | null\n if (target === null) return\n if (target.closest(SIDEBAR_ROW_SELECTOR) !== null) controller.close()\n }\n document.addEventListener('click', onClickSidebarRow, true)\n document.addEventListener(ACTIVATE_EVENT, onOtherActivate)\n const unsubscribe = controller.subscribe(applyActive)\n applyActive()\n ensure()\n\n return () => {\n document.removeEventListener('click', onClickSidebarRow, true)\n document.removeEventListener(ACTIVATE_EVENT, onOtherActivate)\n waitObserver.disconnect()\n unsubscribe()\n document.documentElement.removeAttribute(ACTIVE_ATTR)\n root?.unmount()\n root = undefined\n container?.remove()\n container = undefined\n }\n}\n","/**\n * Sidebar entry injection.\n *\n * dsh's sidebar shell exposes no slot an external plugin can register into,\n * so — following the dsh-ssh / task-board precedent of DOM-level extension —\n * the entry row is injected after the shell's New Session button (after the\n * sibling plugin family block). The injection self-heals: a MutationObserver\n * watches the sidebar root and re-inserts the row whenever a React re-render\n * displaces it (re-insertion happens in the same frame, before paint).\n *\n * The row is plain DOM (no React tree) so it can never disturb the shell's\n * reconciliation; the panel view it toggles is a separate React root mounted\n * in the center column (see mount.tsx).\n */\n\nimport type { ImageGenController } from './controller.ts'\nimport css from './panel.module.css'\n\n/** Stable data attribute identifying the injected entry row. */\nexport const ENTRY_SELECTOR = '[data-dsh-imagegen-entry]'\n\n/** Inline icon (matches the shell's 16px nav-icon look): a picture glyph. */\nconst ICON = '<svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"2\" y=\"2.5\" width=\"12\" height=\"11\" rx=\"1.5\"/><circle cx=\"5.6\" cy=\"5.8\" r=\"1\"/><path d=\"M2.5 12.5l3.6-3.4 2.4 2.2 3-3 2 2.4\"/></svg>'\n\n/** Family entry selectors of sibling plugins (relative placement anchor). */\nconst FAMILY_ENTRY_SELECTOR = '[data-dsh-taskboard-entry], [data-dsh-ssh-entry], [data-dsh-imagegen-entry]'\n\n/** Find the sidebar shell root element, or undefined while not yet mounted. */\nfunction sidebarRoot(): HTMLElement | undefined {\n const column = document.querySelector<HTMLElement>('[data-pane=\"sidebar\"], [class*=\"sidebarCol\"]')\n if (column === null) return undefined\n const logoOwner = column.querySelector<HTMLElement>('[class*=\"logoRow\"]')?.parentElement\n return logoOwner ?? (column.firstElementChild as HTMLElement | undefined)\n}\n\n/** The New Session button: nested in the logo row on current shells, a direct child on legacy shells. */\nfunction newSessionButton(root: HTMLElement): HTMLButtonElement | undefined {\n const nested = root.querySelector<HTMLButtonElement>('button[class*=\"newSession\"]')\n if (nested !== null) return nested\n for (const child of root.children) {\n if (child.tagName === 'BUTTON') return child as HTMLButtonElement\n }\n return undefined\n}\n\n/** Build the entry row (a detached button; insert once the shell is up). */\nfunction createEntry(controller: ImageGenController, label: string, tooltip: string): HTMLButtonElement {\n const entry = document.createElement('button')\n entry.type = 'button'\n entry.dataset.dshImagegenEntry = ''\n entry.className = css.entry\n entry.setAttribute('aria-label', label)\n entry.setAttribute('title', tooltip)\n entry.innerHTML = '<span class=\"' + css.entryIcon + '\">' + ICON + '</span><span class=\"' + css.entryLabel + '\">' + label + '</span>'\n entry.addEventListener('click', () => { controller.toggle() })\n return entry\n}\n\n/** Re-insert the entry after the family block (task board → ssh → imagegen). */\nfunction placeEntry(root: HTMLElement, entry: HTMLButtonElement): boolean {\n const button = newSessionButton(root)\n if (button === undefined) return false\n if (entry.parentElement !== root) {\n // Position relative to the family block, never relative to transient\n // logoRow geometry: every family plugin that self-heals during a\n // re-render then lands in the same relative order.\n const row = button.closest('[class*=\"logoRow\"]')\n const base = (row !== null && row.parentElement === root) ? row : button\n const family = Array.from(root.children).filter(\n (el): el is HTMLElement => el instanceof HTMLElement && el.matches(FAMILY_ENTRY_SELECTOR),\n )\n const anchor = family.length > 0 ? family[family.length - 1].nextElementSibling : base.nextElementSibling\n root.insertBefore(entry, anchor)\n }\n return true\n}\n\n/**\n * Mount the sidebar entry, waiting for the shell to render and self-healing\n * on later React re-renders.\n * @param controller - the panel controller the entry toggles.\n * @param label - the entry label (localized).\n * @param tooltip - the entry tooltip (localized).\n * @returns disposer removing the entry and its observers.\n */\nexport function mountSidebarEntry(controller: ImageGenController, label: string, tooltip: string): () => void {\n const entry = createEntry(controller, label, tooltip)\n let root: HTMLElement | undefined\n let placed = false\n\n const tryPlace = (): void => {\n if (root !== undefined && !root.isConnected) {\n rootObserver.disconnect()\n root = undefined\n placed = false\n }\n if (placed) {\n if (document.body.contains(entry)) return\n rootObserver.disconnect()\n root = undefined\n placed = false\n }\n root ??= sidebarRoot()\n if (root === undefined) return\n placed = placeEntry(root, entry)\n if (placed) {\n rootObserver.observe(root, { childList: true, subtree: true })\n }\n }\n\n // Body-level watcher retained as the \"whole rebuild\" fallback.\n const waitObserver = new MutationObserver(() => { tryPlace() })\n waitObserver.observe(document.body, { childList: true, subtree: true })\n\n // Self-heal: if a React re-render displaces the row, re-insert it in the\n // same frame (microtask before paint -> no visible flicker).\n const rootObserver = new MutationObserver(() => {\n if (root === undefined || !root.isConnected) {\n placed = false\n tryPlace()\n return\n }\n if (!root.contains(entry)) {\n placed = placeEntry(root, entry)\n }\n })\n\n // Reflect the panel's open state on the row (active highlight).\n const syncActive = () => {\n if (controller.getSnapshot().panelOpen) entry.dataset.active = 'true'\n else delete entry.dataset.active\n }\n const unsubscribe = controller.subscribe(syncActive)\n syncActive()\n\n tryPlace()\n\n return () => {\n waitObserver.disconnect()\n rootObserver.disconnect()\n unsubscribe()\n entry.remove()\n }\n}\n","/**\n * Staged form model behind the plugin settings card. A card stages what the\n * user types and writes it only when they save — the settings write is a\n * durable, revision-fenced document mutation, so staging keeps what is on\n * screen exactly what a save would store. Self-contained slice of the same\n * pattern the dsh-web-ui family cards use (this package must not depend on a\n * sibling UI package).\n */\n\nimport { createSnapshotStore, type SettingsScope, type SettingsScopeSnapshot, type SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'\n\n/** The write one field's staged text performs when the card is saved. */\nexport type FieldWrite =\n | { kind: 'set'; value: unknown }\n | { kind: 'clear' }\n\n/** How one field converts between its stored value and its draft text. */\nexport interface FieldSpec {\n /** Field name inside the namespace section. */\n field: string\n /** Render a stored value as draft text; the empty string when the section carries none. */\n format: (value: unknown) => string\n /**\n * The write this draft text stages, or undefined when the text is not a\n * value this field accepts — which blocks the save rather than discarding it.\n */\n parse: (text: string) => FieldWrite | undefined\n /**\n * True for secret fields (role('secret') in the namespace schema): the\n * redacted wire view never returns the stored value, so the form treats an\n * empty draft as \"no change\" and judges writes by the namespace's secrets\n * sidecar instead of the user layer.\n */\n secret?: boolean\n}\n\n/** One field as the card renders it. */\nexport interface FieldState {\n /** Draft text the control renders. */\n text: string\n /** Whether saving would leave a user-layer entry for this field. */\n overridden: boolean\n /** Whether the draft is not a value this field accepts, which blocks saving. */\n invalid: boolean\n}\n\n/** Form state every plugin settings card shares. */\nexport interface CardShell {\n /** False while the namespace is still loading; the card renders nothing. */\n available: boolean\n /** Whether the namespace is actually served (the bridge answered). */\n exposed: boolean\n /** Whether the Host document accepts writes. */\n writable: boolean\n /** Whether the form holds edits that a save would write. */\n dirty: boolean\n /** Whether any staged draft is invalid, which blocks the save. */\n invalid: boolean\n /** Whether a save is crossing the wire. */\n saving: boolean\n /** Whether the last save did not land as staged; cleared by the next edit or save. */\n failed: boolean\n}\n\n/** The write actions the card's slot entry injects. */\nexport interface CardActions {\n /** Stage draft text for one field. */\n edit: (field: string, text: string) => void\n /** Stage a clear, so saving lets the field re-inherit the composition layer. */\n resetField: (field: string) => void\n /** Write every staged edit, then re-seed from what the Host accepted. */\n save: () => void\n /** Drop every staged edit. */\n discard: () => void\n}\n\n/** One field's staged edit. */\ninterface StagedEdit {\n /** Draft text the control renders. */\n text: string\n /** True when this edit clears the field whatever text it shows. */\n clear: boolean\n}\n\n/** One staged edit resolved into the write a save performs. */\ninterface PlannedWrite {\n /** Field this entry writes. */\n field: string\n /** Perform the write and report whether the Host holds the staged value afterwards. */\n run: (() => Promise<boolean>) | undefined\n}\n\n/** A free-text field. An empty draft clears the field. */\nexport function textField(field: string): FieldSpec {\n return {\n field,\n format: value => typeof value === 'string' ? value : '',\n parse: (text) => {\n const trimmed = text.trim()\n return trimmed === '' ? { kind: 'clear' } : { kind: 'set', value: trimmed }\n },\n }\n}\n\n/** A newline/comma-separated model list, persisted as a normalized string array. */\nexport function stringListField(field: string): FieldSpec {\n return {\n field,\n format: value => Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string').join('\\n') : '',\n parse: (text) => {\n const values = [...new Set(text.split(/[\\n,]/).map(item => item.trim()).filter(Boolean))]\n return values.length === 0 ? { kind: 'clear' } : { kind: 'set', value: values }\n },\n }\n}\n\n/** A boolean field, edited through true/false draft text. */\nexport function booleanField(field: string): FieldSpec {\n return {\n field,\n format: value => typeof value === 'boolean' ? String(value) : '',\n parse: (text) => {\n if (text === 'true') return { kind: 'set', value: true }\n if (text === 'false') return { kind: 'set', value: false }\n return undefined\n },\n }\n}\n\n/**\n * A secret field (role('secret') in the namespace schema). The stored value is\n * never rendered or returned by the redacted wire view, so:\n * - an empty draft means \"no change\" (typing nothing must never clear an\n * invisible stored key); the dedicated clear action stages an explicit clear;\n * - a write's outcome is judged by the namespace's secrets sidecar through\n * the {@link CardForm} `secretSettled` hook, never by the user layer.\n */\nexport function secretField(field: string): FieldSpec {\n return {\n field,\n secret: true,\n format: () => '',\n parse: (text) => {\n const trimmed = text.trim()\n if (trimmed === '') return undefined\n return { kind: 'set', value: trimmed }\n },\n }\n}\n\n/**\n * Stages one card's edits over one settings scope and writes them on save.\n *\n * The Host is the only authority on whether a value was accepted — its\n * validators own the constraints no schema can express — so the outcome is\n * read back from the section rather than predicted here. A save that did not\n * land keeps its drafts, so the user can correct them instead of retyping.\n */\nexport class CardForm<T> {\n private readonly specs: Map<string, FieldSpec>\n private readonly staged = new Map<string, StagedEdit>()\n private readonly listeners = new Set<() => void>()\n private saving = false\n private failed = false\n\n /**\n * @param scope - the bound settings scope for this card's namespace.\n * @param specs - the fields this card edits.\n * @param options.secretSettled - for secret fields, whether the namespace\n * currently holds a stored secret (the redacted view never round-trips the\n * value, so a write's outcome is read from the secrets sidecar instead).\n */\n constructor(\n private readonly scope: SettingsScope<T>,\n specs: FieldSpec[],\n private readonly options: { secretSettled?: (field: string) => boolean } = {},\n ) {\n this.specs = new Map(specs.map(spec => [spec.field, spec]))\n scope.subscribe(() => { this.publish() })\n }\n\n /** Publish a projection of this form, rebuilt whenever the scope or a draft changes. */\n bind<S>(project: () => S): SnapshotStore<S> {\n const store = createSnapshotStore(project())\n this.listeners.add(() => { store.set(project()) })\n return store\n }\n\n /** Read the card-level state: what the Host serves, and what a save would do. */\n shell(): CardShell {\n const snapshot = this.scope.getSnapshot()\n const plan = this.plan()\n return {\n available: snapshot.status !== 'loading',\n exposed: snapshot.status === 'ready',\n writable: snapshot.writable,\n dirty: plan.length > 0,\n invalid: plan.some(item => item.run === undefined),\n saving: this.saving,\n failed: this.failed,\n }\n }\n\n /** Read one field's state from the effective section and its staged draft. */\n field(field: string): FieldState {\n const spec = this.specOf(field)\n const staged = this.staged.get(field)\n if (staged === undefined) {\n return { text: spec.format(this.sectionValue(field)), overridden: this.stored(field), invalid: false }\n }\n const write = staged.clear ? { kind: 'clear' as const } : spec.parse(staged.text)\n return {\n text: staged.text,\n overridden: write?.kind === 'set',\n // A secret field's empty draft is \"no change\" (see secretField), never\n // an invalid state — the stored value is invisible, so the user cannot\n // be expected to type over it.\n invalid: write === undefined && !(spec.secret === true && staged.text.trim() === ''),\n }\n }\n\n /** The actions the card's slot registration injects. */\n actions(): CardActions {\n return {\n edit: (field, text) => { this.stage(field, { text, clear: false }) },\n resetField: (field) => {\n this.stage(field, { text: this.specOf(field).format(this.baseValue(field)), clear: true })\n },\n save: () => { void this.save() },\n discard: () => {\n if (this.staged.size === 0 && !this.failed) return\n this.staged.clear()\n this.failed = false\n this.publish()\n },\n }\n }\n\n /**\n * Write every staged edit, then re-seed from what the Host accepted.\n * @returns settlement after every write and the read-back.\n */\n async save(): Promise<void> {\n const plan = this.plan()\n const writes = plan.flatMap(item => item.run === undefined ? [] : [item.run])\n if (plan.length === 0 || this.saving || writes.length !== plan.length) return\n this.saving = true\n this.failed = false\n this.publish()\n let landed = true\n for (const write of writes) {\n landed = await write() && landed\n }\n if (landed) this.staged.clear()\n this.saving = false\n this.failed = !landed\n this.publish()\n }\n\n /**\n * Every staged edit a save would write. An entry whose draft is not a value\n * its field accepts carries no write: the form is still dirty, and the save\n * refuses rather than dropping the edit. A staged edit that matches the\n * effective section is not a write at all.\n */\n private plan(): PlannedWrite[] {\n const plan: PlannedWrite[] = []\n for (const [field, staged] of this.staged) {\n const spec = this.specOf(field)\n if (staged.clear) {\n const present = spec.secret === true\n ? (this.options.secretSettled?.(field) ?? false)\n : this.stored(field)\n if (present) plan.push({ field, run: () => this.clear(field) })\n continue\n }\n if (staged.text === spec.format(this.sectionValue(field))) continue\n const write = spec.parse(staged.text)\n if (write === undefined) plan.push({ field, run: undefined })\n else if (write.kind === 'clear') plan.push({ field, run: () => this.clear(field) })\n else plan.push({ field, run: () => this.store(field, write.value) })\n }\n return plan\n }\n\n private async clear(field: string): Promise<boolean> {\n await this.scope.unset(field)\n const spec = this.specOf(field)\n if (spec.secret === true) return !(this.options.secretSettled?.(field) ?? false)\n return !this.stored(field)\n }\n\n private async store(field: string, value: unknown): Promise<boolean> {\n await this.scope.set(field, value)\n const spec = this.specOf(field)\n if (spec.secret === true) return this.options.secretSettled?.(field) ?? true\n return this.userLayer()?.[field] === value\n }\n\n private stage(field: string, edit: StagedEdit): void {\n this.staged.set(field, edit)\n this.failed = false\n this.publish()\n }\n\n private specOf(field: string): FieldSpec {\n const spec = this.specs.get(field)\n if (spec === undefined) throw new Error(`settings card has no field ${field}`)\n return spec\n }\n\n private snapshotOf(): SettingsScopeSnapshot<T> {\n return this.scope.getSnapshot()\n }\n\n private sectionValue(field: string): unknown {\n return (this.snapshotOf().value as Record<string, unknown> | undefined)?.[field]\n }\n\n private baseValue(field: string): unknown {\n return (this.snapshotOf().base as Record<string, unknown> | undefined)?.[field]\n }\n\n private userLayer(): Record<string, unknown> | undefined {\n return this.snapshotOf().user as Record<string, unknown> | undefined\n }\n\n private stored(field: string): boolean {\n const user = this.userLayer()\n return user !== undefined && Object.hasOwn(user, field)\n }\n\n private publish(): void {\n for (const listener of [...this.listeners]) listener()\n }\n}\n","/**\n * Staged form model for the channel list of the settings card. Mirrors the\n * CardForm staging pattern (dirty → one save) but for a structured value, so\n * the card can edit N channels, per-channel keys, and the default-channel\n * flag, then persist everything in one revision-fenced mutate call.\n *\n * Storage rules (dictated by dsh-settings semantics):\n * - the whole `channels` array is written wholesale via `path: ['channels']`;\n * - every channel's API key lives at `channelSecrets.<channelId>` (a secret\n * dict), written per-key so untouched keys are never clobbered by a save\n * the reader could not see (keys are redacted out of the wire view);\n * - path ops never navigate *inside* the channels array.\n */\n\nimport { createSnapshotStore, type SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { ChannelConfig, ModelMapping } from '../protocol.ts'\nimport type { ImageGenScope, SettingsOp } from './settings-scope.ts'\n\n/** One channel as the editor stages it (secrets never travel here). */\nexport interface ChannelDraft {\n id: string\n preset: string\n name: string\n apiUrl: string\n models: ModelMapping[]\n}\n\n/** One staged key edit for a channel. */\nexport type KeyEdit = { kind: 'set'; value: string } | { kind: 'clear' }\n\n/** The state the card renders. */\nexport interface ChannelsFormState {\n /** Staged channel list (the scope value when nothing is staged). */\n channels: ChannelDraft[]\n /** Which channels currently hold a stored secret (staged edits included). */\n keySet: Record<string, boolean>\n /** The effective default channel id. */\n defaultChannelId: string\n /** Whether a save would write anything. */\n dirty: boolean\n /** Whether the document accepts writes. */\n writable: boolean\n /** Whether a save is crossing the wire. */\n saving: boolean\n /** Whether the last save failed (cleared by the next edit or save). */\n failed: boolean\n}\n\n/** The actions the card's slot entry injects. */\nexport interface ChannelsFormActions {\n /** Replace the whole channel list (add/edit/remove go through here). */\n setChannels: (channels: ChannelDraft[]) => void\n /** Stage a key for one channel ('' clears; undefined = no staged change). */\n setChannelKey: (id: string, value: string | undefined) => void\n /** Stage the default-channel flag. */\n setDefaultChannel: (id: string) => void\n /** Write every staged edit, then re-seed from what the Host accepted. */\n commit: () => Promise<void>\n /** Drop every staged edit. */\n discard: () => void\n}\n\n/** Deep equality over JSON-compatible data (the change predicate). */\nfunction deepEqualJson(a: unknown, b: unknown): boolean {\n if (a === b) return true\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false\n if (Array.isArray(a) || Array.isArray(b)) {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false\n return a.every((entry, index) => deepEqualJson(entry, b[index]))\n }\n const left = a as Record<string, unknown>\n const right = b as Record<string, unknown>\n const keys = Object.keys(left)\n if (keys.length !== Object.keys(right).length) return false\n return keys.every(key => key in right && deepEqualJson(left[key], right[key]))\n}\n\n/** Trim and normalize a draft channel (models never carry empty aliases). */\nfunction stripChannel(channel: ChannelDraft): ChannelDraft {\n const models = channel.models\n .map(model => ({ alias: model.alias.trim(), id: model.id.trim() === '' ? model.alias.trim() : model.id.trim() }))\n .filter(model => model.alias !== '')\n return {\n id: channel.id,\n preset: channel.preset,\n name: channel.name.trim(),\n apiUrl: channel.apiUrl.trim(),\n models: [...new Map(models.map(model => [model.alias, model])).values()],\n }\n}\n\nexport class ChannelsForm {\n private stagedChannels: ChannelDraft[] | null = null\n private readonly stagedKeys = new Map<string, KeyEdit>()\n private stagedDefault: string | null = null\n private readonly listeners = new Set<() => void>()\n private saving = false\n private failed = false\n\n constructor(private readonly scope: ImageGenScope) {\n scope.subscribe(() => { this.publish() })\n scope.subscribeSecretSets(() => { this.publish() })\n }\n\n /** Publish a projection of this form, rebuilt on every scope or draft change. */\n bind<S>(project: () => S): SnapshotStore<S> {\n const store = createSnapshotStore(project())\n this.listeners.add(() => { store.set(project()) })\n return store\n }\n\n /** Subscribe to staged and persisted channel changes. */\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => { this.listeners.delete(listener) }\n }\n\n /** The staged channel list, or the scope value when nothing is staged. */\n private channelsValue(): ChannelDraft[] {\n const view = this.scope.getSnapshot().value as { channels?: ChannelConfig[] } | undefined\n return this.stagedChannels ?? (Array.isArray(view?.channels) ? view.channels.map(toDraft) : [])\n }\n\n /** Whether a channel currently holds a stored or staged secret. */\n private keyHeld(id: string): boolean {\n const edit = this.stagedKeys.get(id)\n if (edit !== undefined) return edit.kind === 'set' && edit.value !== ''\n return this.scope.getSecretSetSnapshot(`channelSecrets.${id}`)\n }\n\n private defaultValue(): string {\n if (this.stagedDefault !== null) return this.stagedDefault\n const view = this.scope.getSnapshot().value as { defaultChannelId?: string } | undefined\n const channels = this.channelsValue()\n if (view?.defaultChannelId !== undefined && channels.some(channel => channel.id === view.defaultChannelId)) return view.defaultChannelId\n return channels[0]?.id ?? ''\n }\n\n private dirtyValue(): boolean {\n const channels = this.channelsValue()\n const stagedChanged = this.stagedChannels !== null && !deepEqualJson(this.stagedChannels, scopeChannelsOf(this.scope))\n const scopeView = this.scope.getSnapshot().value as { defaultChannelId?: string } | undefined\n const scopeDefault = scopeView?.defaultChannelId ?? channels[0]?.id ?? ''\n const defaultChanged = this.stagedDefault !== null && this.stagedDefault !== scopeDefault\n return stagedChanged || defaultChanged || this.stagedKeys.size > 0\n }\n\n /** The card-facing snapshot. */\n snapshot(): ChannelsFormState {\n const channels = this.channelsValue()\n const keySet: Record<string, boolean> = {}\n for (const channel of channels) keySet[channel.id] = this.keyHeld(channel.id)\n return {\n channels,\n keySet,\n defaultChannelId: this.defaultValue(),\n dirty: this.dirtyValue(),\n writable: this.scope.getSnapshot().writable !== false,\n saving: this.saving,\n failed: this.failed,\n }\n }\n\n /** The actions the card's slot registration injects. */\n actions(): ChannelsFormActions {\n return {\n setChannels: (channels) => { this.stageChannels(channels) },\n setChannelKey: (id, value) => { this.stageKey(id, value) },\n setDefaultChannel: (id) => { this.stagedDefault = id; this.failed = false; this.publish() },\n commit: () => this.commit(),\n discard: () => {\n if (this.stagedChannels === null && this.stagedKeys.size === 0 && this.stagedDefault === null && !this.failed) return\n this.stagedChannels = null\n this.stagedKeys.clear()\n this.stagedDefault = null\n this.failed = false\n this.publish()\n },\n }\n }\n\n // ------------------------------------------------------------------ staging\n\n private stageChannels(channels: ChannelDraft[]): void {\n const cleaned = channels.map(stripChannel)\n this.stagedChannels = cleaned\n this.failed = false\n this.publish()\n }\n\n private stageKey(id: string, value: string | undefined): void {\n if (value === undefined || value.trim() === '') {\n if (this.keyHeld(id)) this.stagedKeys.set(id, { kind: 'clear' })\n // An empty key for a key-less channel stages nothing.\n } else {\n this.stagedKeys.set(id, { kind: 'set', value: value.trim() })\n }\n this.failed = false\n this.publish()\n }\n\n // ----------------------------------------------------------------- save\n\n /** Build the single batch of path ops a save performs. */\n private planOps(): SettingsOp[] {\n const ops: SettingsOp[] = []\n if (this.stagedChannels !== null) {\n ops.push({ op: 'set', path: ['channels'], value: this.stagedChannels })\n // Once channels exist, the legacy flat fields are obsolete (idempotent).\n ops.push({ op: 'unset', path: ['apiUrl'] })\n ops.push({ op: 'unset', path: ['apiKey'] })\n ops.push({ op: 'unset', path: ['imageModels'] })\n }\n for (const [id, edit] of this.stagedKeys) {\n if (edit.kind === 'set') ops.push({ op: 'set', path: ['channelSecrets', id], value: edit.value })\n else ops.push({ op: 'unset', path: ['channelSecrets', id] })\n }\n if (this.stagedDefault !== null) {\n ops.push({ op: 'set', path: ['defaultChannelId'], value: this.stagedDefault })\n }\n return ops\n }\n\n /**\n * Write every staged edit, then re-seed from what the Host accepted.\n * @returns settlement after the write settles.\n */\n async commit(): Promise<void> {\n if (this.saving) return\n const ops = this.planOps()\n if (ops.length === 0) return\n this.saving = true\n this.failed = false\n this.publish()\n try {\n await this.scope.mutateOps(ops)\n this.stagedChannels = null\n this.stagedKeys.clear()\n this.stagedDefault = null\n this.failed = false\n } catch {\n this.failed = true\n } finally {\n this.saving = false\n this.publish()\n }\n }\n\n private publish(): void {\n for (const listener of [...this.listeners]) listener()\n }\n}\n\n/** Project a stored channel into a draft (secrets never travel in channels). */\nfunction toDraft(channel: ChannelConfig): ChannelDraft {\n return { id: channel.id, preset: channel.preset, name: channel.name, apiUrl: channel.apiUrl, models: channel.models.map(model => ({ ...model })) }\n}\n\n/** The scope's current channels value (a plain array), for change detection. */\nfunction scopeChannelsOf(scope: ImageGenScope): unknown {\n const view = scope.getSnapshot().value as { channels?: unknown } | undefined\n return Array.isArray(view?.channels) ? view.channels : []\n}\n","/**\n * Model catalog: protocol-family detection and capability annotation shared by\n * the engine, the settings card, and the panel. Known id patterns map onto the\n * OpenAI-compatible image protocol families this plugin shapes requests for;\n * anything unrecognized falls back to the generic OpenAI protocol (best\n * effort) and is flagged as unknown so the UI can warn without blocking.\n *\n * Framework-free (pure data + regex), safe for the client bundle to inline.\n */\n\nexport type ModelFamily = 'gpt-image' | 'dall-e' | 'grok' | 'nanobanana' | 'seedream' | 'unknown'\n\n/** Capability/identity annotation for one model id. */\nexport interface ModelCatalogEntry {\n /** Family the request is shaped for. */\n family: ModelFamily\n /** Short badge label (en). */\n label: string\n /** Short badge label (zh). */\n labelZh: string\n /** Whether the family is known (false = best-effort OpenAI protocol). */\n known: boolean\n /** Whether the family supports image-to-image edits. */\n supportsEdit: boolean\n /** Whether the family natively takes aspect-ratio dials. */\n supportsAspectRatio: boolean\n /** Quality tiers the family interprets natively. */\n qualityTiers: string[]\n}\n\nconst ENTRIES: Record<Exclude<ModelFamily, 'unknown'>, Omit<ModelCatalogEntry, 'family'>> = {\n 'gpt-image': {\n label: 'gpt-image',\n labelZh: 'GPT 图像',\n known: true,\n supportsEdit: true,\n supportsAspectRatio: false,\n qualityTiers: ['1K', '2K', '4K'],\n },\n 'dall-e': {\n label: 'DALL·E',\n labelZh: 'DALL·E',\n known: true,\n supportsEdit: true,\n supportsAspectRatio: false,\n qualityTiers: ['auto'],\n },\n grok: {\n label: 'grok',\n labelZh: 'Grok',\n known: true,\n supportsEdit: true,\n supportsAspectRatio: true,\n qualityTiers: ['1K', '2K'],\n },\n nanobanana: {\n label: 'nanobanana',\n labelZh: 'Nano Banana',\n known: true,\n supportsEdit: true,\n supportsAspectRatio: true,\n qualityTiers: ['1K', '2K', '4K'],\n },\n seedream: {\n label: 'seedream',\n labelZh: 'Seedream',\n known: true,\n supportsEdit: true,\n supportsAspectRatio: true,\n qualityTiers: ['1K', '2K'],\n },\n}\n\n/** Official Gemini image ids served by Nano Banana gateways. */\nconst NANOBANANA_GEMINI_IDS = new Set([\n 'gemini-3-pro-image',\n 'gemini-3-pro-image-preview',\n 'gemini-3.1-flash-image',\n 'gemini-3.1-flash-image-preview',\n 'gemini-3.1-flash-lite-image',\n 'gemini-2.5-flash-image',\n])\n\n/** Classify one upstream model id into its request-shaping family. */\nexport function describeModel(model: string): ModelCatalogEntry {\n const id = model.trim()\n if (/^gpt-image/i.test(id)) return { family: 'gpt-image', ...ENTRIES['gpt-image'] }\n if (/^dall-e/i.test(id)) return { family: 'dall-e', ...ENTRIES['dall-e'] }\n if (/^grok-imagine(?:-|$)/.test(id)) return { family: 'grok', ...ENTRIES.grok }\n if (/^nanobanana/i.test(id) || NANOBANANA_GEMINI_IDS.has(id)) return { family: 'nanobanana', ...ENTRIES.nanobanana }\n if (/^(?:doubao-)?seedream/i.test(id)) return { family: 'seedream', ...ENTRIES.seedream }\n return { family: 'unknown', label: 'unknown', labelZh: '未知协议', known: false, supportsEdit: true, supportsAspectRatio: false, qualityTiers: [] }\n}\n\n/** The family a model id routes its request through. */\nexport function modelFamily(model: string): ModelFamily {\n return describeModel(model).family\n}","/**\n * The dsh-imagegen settings card: channel management (list rows with status\n * dots, an editor dialog with the model-catalog alias → upstream mapping, and\n * built-in provider presets), plus the prompt-enhancement model and the plugin\n * switches. Registers into the official `settings.plugin.item` slot (the\n * Settings → Plugins → Configurable tab), independent of the dsh-web-ui family\n * group, bound to the plugin's own bridge settings scope.\n *\n * The interaction mirrors the host's model-provider page: one row per channel\n * (status dot + edit/delete), two add buttons (built-in provider / custom),\n * and an editor holding API key, display name, API URL, and the model catalog\n * with detection.\n */\n\nimport { useEffect, useRef, useState } from 'react'\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { createSnapshotStore, type SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'\nimport { CardForm, booleanField, secretField, textField, type CardActions, type CardShell, type FieldState as CardFieldState } from './settings-form.ts'\nimport { ChannelsForm, type ChannelDraft, type ChannelsFormActions, type ChannelsFormState } from './channels-form.ts'\nimport type { ImageGenScope } from './settings-scope.ts'\nimport { describeModel } from '../model-catalog.ts'\nimport { IMAGE_MODEL_API, PRESETS_API, PROMPT_ENHANCE_API, USAGE_API, type ModelMapping, type PresetProviderView } from '../protocol.ts'\nimport type { ImageGenKey } from './locales.ts'\nimport css from './settings-card.module.css'\n\n/** The global (non-channel) fields this card's staged form edits. */\nexport interface ImageGenSettings {\n enabled?: boolean\n announceToAgent?: boolean\n allowAgentImageGeneration?: boolean\n promptApiUrl?: string\n promptApiKey?: string\n promptModel?: string\n}\n\n/** What the card renders. */\nexport interface ImageGenSettingsCardState extends CardShell {\n /** Channel list staging (channels + per-channel key edits + default). */\n channels: ChannelsFormState\n /** Master switch. */\n enabled: CardFieldState\n /** System-prompt announcement flag. */\n announceToAgent: CardFieldState\n allowAgentImageGeneration: CardFieldState\n promptApiUrl: CardFieldState\n promptApiKey: CardFieldState\n promptModel: CardFieldState\n}\n\n/** The registration-side face the card's slot entry injects. */\nexport interface ImageGenSettingsCardFace extends CardActions {\n /** Channel staging actions (committed together with the card's save). */\n channels: ChannelsFormActions\n hooks: {\n /** Card snapshot bound by the renderer as useImageGenSettingsCard. */\n imageGenSettingsCard: SnapshotStore<ImageGenSettingsCardState>\n }\n}\n\n/** Bridges the imagegen scope onto the card's staged forms. */\nexport class ImageGenSettingsCardController {\n private readonly form: CardForm<ImageGenSettings>\n private readonly channelsForm: ChannelsForm\n\n /** @param scope - the bound bridge scope for the dsh-imagegen namespace. */\n constructor(private readonly scope: ImageGenScope) {\n this.form = new CardForm(scope, [\n booleanField('enabled'),\n booleanField('announceToAgent'),\n booleanField('allowAgentImageGeneration'),\n textField('promptApiUrl'),\n secretField('promptApiKey'),\n textField('promptModel'),\n ], {\n secretSettled: () => this.scope.getSecretSetSnapshot('promptApiKey'),\n })\n this.channelsForm = new ChannelsForm(scope)\n }\n\n private projection(): ImageGenSettingsCardState {\n const shell = this.form.shell()\n return {\n ...shell,\n dirty: shell.dirty || this.channelsForm.snapshot().dirty,\n channels: this.channelsForm.snapshot(),\n enabled: this.form.field('enabled'),\n announceToAgent: this.form.field('announceToAgent'),\n allowAgentImageGeneration: this.form.field('allowAgentImageGeneration'),\n promptApiUrl: this.form.field('promptApiUrl'),\n promptApiKey: this.form.field('promptApiKey'),\n promptModel: this.form.field('promptModel'),\n }\n }\n\n /**\n * Build the face the card's slot registration injects.\n * @returns the card's snapshot and the form/channel actions.\n */\n inject(): ImageGenSettingsCardFace {\n const cardStore = this.form.bind(() => this.projection())\n this.channelsForm.subscribe(() => { cardStore.set(this.projection()) })\n return {\n hooks: {\n imageGenSettingsCard: cardStore,\n },\n channels: this.channelsForm.actions(),\n ...this.form.actions(),\n }\n }\n}\n\n/** Props the renderer binds for this card. */\nexport type ImageGenSettingsCardProps =\n PropsRuntime<'settings.plugin.item'>\n & PropsLocale<'dsh-imagegen'>\n & InjectFace<ImageGenSettingsCardFace>\n\n/** Host-computed usage counters (generation-count badges). */\ninterface UsageCounters {\n byChannel: Record<string, Record<string, number>>\n totals: Record<string, number>\n}\n\n/**\n * Render the card.\n * @param props - locale copy, the card snapshot, and the form actions.\n * @returns the card, or nothing while the namespace is still loading.\n */\nexport function ImageGenSettingsCard(props: ImageGenSettingsCardProps) {\n const { t } = props\n const state = props.useImageGenSettingsCard(snapshot => snapshot)\n const [open, setOpen] = useState(false)\n // Global-section local states (prompt enhancement etc.).\n const [promptModels, setPromptModels] = useState<string[]>([])\n const [loadingPromptModels, setLoadingPromptModels] = useState(false)\n const [promptModelsError, setPromptModelsError] = useState<string | null>(null)\n const [manualPromptModelOpen, setManualPromptModelOpen] = useState(false)\n const [manualPromptModel, setManualPromptModel] = useState('')\n const [enhancementOpen, setEnhancementOpen] = useState(false)\n const [promptApiOpen, setPromptApiOpen] = useState(false)\n const [moreOpen, setMoreOpen] = useState(false)\n // Channel list local states.\n const [editingId, setEditingId] = useState<string | null>(null)\n const [presetPickerOpen, setPresetPickerOpen] = useState(false)\n const [presets, setPresets] = useState<PresetProviderView[]>([])\n const [presetError, setPresetError] = useState<string | null>(null)\n const [usage, setUsage] = useState<UsageCounters | null>(null)\n const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null)\n\n // Usage counters: refreshed once per card open (and after a successful save).\n useEffect(() => {\n if (!state.exposed) return\n let alive = true\n void fetch(USAGE_API, { method: 'POST' })\n .then(async response => { const body = await response.json() as { ok?: boolean; usage?: UsageCounters }; if (alive && body.ok === true && body.usage !== undefined) setUsage(body.usage) })\n .catch(() => { /* counters are best-effort */ })\n return () => { alive = false }\n }, [state.exposed])\n\n if (!state.available) return null\n const title = t('settings.title')\n const blocked = !state.dirty || state.invalid || state.saving || state.channels.saving\n const disabled = !state.writable\n const fieldProps = {\n overriddenLabel: t('settings.overridden'),\n resetLabel: t('settings.reset'),\n invalidLabel: t('settings.invalidNumber'),\n disabled,\n }\n\n if (!state.exposed) {\n return (\n <li className={css.card}>\n <button\n type=\"button\"\n className={css.header}\n aria-expanded={open}\n aria-label={`${t(open ? 'settings.collapse' : 'settings.expand')}: ${title}`}\n onClick={() => { setOpen(!open) }}\n >\n <span className={css.headText}>\n <span className={css.name}>{title}</span>\n <span className={css.description}>{t('settings.description')}</span>\n </span>\n <span className={open ? css.chevronOpen : css.chevron}>▾</span>\n </button>\n {open\n ? (\n <div className={css.body}>\n <p className={css.notExposed} role=\"status\">{t('settings.notExposed')}</p>\n </div>\n )\n : null}\n </li>\n )\n }\n\n const channels = state.channels.channels\n const editing = editingId === null ? undefined : channels.find(channel => channel.id === editingId)\n\n return (\n <li className={css.card}>\n <button\n type=\"button\"\n className={css.header}\n aria-expanded={open}\n aria-label={`${t(open ? 'settings.collapse' : 'settings.expand')}: ${title}`}\n onClick={() => { setOpen(!open) }}\n >\n <span className={css.headText}>\n <span className={css.name}>{title}</span>\n <span className={css.description}>{t('settings.description')}</span>\n </span>\n {state.dirty ? <span className={css.pending}>{t('settings.unsaved')}</span> : null}\n <span className={open ? css.chevronOpen : css.chevron}>▾</span>\n </button>\n {open\n ? (\n <div className={css.body}>\n {!state.writable ? <p className={css.readOnly} role=\"status\">{t('settings.readOnly')}</p> : null}\n\n <section className={css.channelSection} aria-label={t('channels.title')}>\n <div className={css.sectionHeader}>\n <div>\n <h3 className={css.sectionTitle}>{t('channels.title')}</h3>\n <p className={css.sectionHint}>{t('channels.hint')}</p>\n </div>\n </div>\n {channels.length === 0\n ? <p className={css.channelEmpty}>{t('channels.empty')}</p>\n : (\n <ul className={css.channelList}>\n {channels.map(channel => {\n const keyHeld = state.channels.keySet[channel.id] === true\n const ready = keyHeld && channel.models.length > 0\n const isDefault = channel.id === state.channels.defaultChannelId\n if (confirmDeleteId === channel.id) {\n return (\n <li key={channel.id} className={css.channelRow} data-action>\n <span className={css.deleteConfirmText}>{t('channels.deleteConfirmTitle', { name: channel.name || t('channels.untitled') })}</span>\n <button type=\"button\" className={css.channelDanger} disabled={disabled} onClick={() => { props.channels.setChannels(channels.filter(candidate => candidate.id !== channel.id)); if (isDefault && channels.length > 1) { const next = channels.find(candidate => candidate.id !== channel.id); if (next !== undefined) props.channels.setDefaultChannel(next.id) } setConfirmDeleteId(null); if (editingId === channel.id) setEditingId(null) }}>{t('channels.confirm')}</button>\n <button type=\"button\" className={css.channelAction} disabled={disabled} onClick={() => { setConfirmDeleteId(null) }}>{t('channels.cancel')}</button>\n </li>\n )\n }\n return (\n <li key={channel.id} className={css.channelRow}>\n <span className={ready ? css.channelDotReady : css.channelDotWarn} aria-hidden=\"true\" title={t(ready ? 'channels.statusReady' : 'channels.statusIncomplete')} />\n <button type=\"button\" className={css.channelMain} disabled={disabled} onClick={() => { setEditingId(channel.id) }}>\n <span className={css.channelName}>{isDefault ? `★ ${channel.name || t('channels.untitled')}` : (channel.name || t('channels.untitled'))}</span>\n <span className={css.channelMeta}>\n {channel.apiUrl !== '' ? <span className={css.channelHost}>{hostOf(channel.apiUrl)}</span> : null}\n <span className={css.channelBadge} data-warn={keyHeld ? undefined : ''}>{keyHeld ? t('channels.keySet') : t('channels.keyMissing')}</span>\n <span className={css.channelBadge} data-warn={channel.models.length > 0 ? undefined : ''}>{channel.models.length > 0 ? t('channels.modelCount', { n: channel.models.length }) : t('channels.noModels')}</span>\n {isDefault ? <span className={css.channelBadge} data-default>{t('channels.defaultLabel')}</span> : null}\n </span>\n </button>\n <button type=\"button\" className={css.channelAction} onClick={() => { setEditingId(channel.id) }}>{t('channels.edit')}</button>\n <button type=\"button\" className={css.channelAction} data-danger onClick={() => { setConfirmDeleteId(channel.id) }}>{t('channels.delete')}</button>\n </li>\n )\n })}\n </ul>\n )}\n <div className={css.channelControls}>\n {open && presetPickerOpen ? (\n <PresetPicker\n t={t}\n presets={presets}\n error={presetError}\n disabled={state.writable === false}\n onLoad={() => {\n setPresetError(null)\n void fetch(PRESETS_API, { method: 'POST' })\n .then(async response => {\n const body = await response.json() as { ok?: boolean; presets?: PresetProviderView[]; message?: string }\n if (!response.ok || body.ok !== true || body.presets === undefined) throw new Error(body.message ?? `HTTP ${response.status}`)\n setPresets(body.presets)\n })\n .catch(error => { setPresetError(error instanceof Error ? error.message : String(error)) })\n }}\n onPick={(preset) => {\n const draft = newChannelDraft(preset)\n props.channels.setChannels([...channels, draft])\n setPresetPickerOpen(false)\n setEditingId(draft.id)\n }}\n onCustom={() => {\n const draft = newChannelDraft(undefined)\n props.channels.setChannels([...channels, draft])\n setPresetPickerOpen(false)\n setEditingId(draft.id)\n }}\n onClose={() => { setPresetPickerOpen(false) }}\n />\n ) : null}\n\n <div className={css.channelAddRow}>\n <button type=\"button\" className={css.channelAdd} disabled={disabled} onClick={() => { setPresetError(null); setPresetPickerOpen(true) }}>+ {t('channels.addProvider')}</button>\n <button type=\"button\" className={css.channelAdd} disabled={disabled} onClick={() => { addCustomChannel(channels, props.channels, setEditingId) }}>+ {t('channels.addCustom')}</button>\n </div>\n </div>\n </section>\n\n <button\n type=\"button\"\n className={css.disclosure}\n aria-expanded={enhancementOpen}\n onClick={() => { setEnhancementOpen(open => !open) }}\n >\n <span>{t('settings.promptEnhanceTitle')}</span>\n <span>{t('settings.optional')}</span>\n <span aria-hidden=\"true\">{enhancementOpen ? '⌃' : '⌄'}</span>\n </button>\n {enhancementOpen ? <section className={css.optionalContent} aria-label={t('settings.promptEnhanceTitle')}>\n <p className={css.sectionHint}>{t('settings.promptEnhanceHint')}</p>\n <div className={css.sectionHeader}>\n <div>\n <h3 className={css.sectionTitle}>{t('settings.promptModel')}</h3>\n <p className={css.sectionHint}>{t('settings.promptModelDetectionHint')}</p>\n </div>\n <button\n type=\"button\"\n className={css.modelFetch}\n disabled={disabled || loadingPromptModels}\n onClick={() => {\n setLoadingPromptModels(true)\n setPromptModelsError(null)\n void fetch(PROMPT_ENHANCE_API.models, { method: 'POST' })\n .then(async response => {\n const body = await response.json() as { ok?: boolean; models?: string[]; message?: string }\n if (!response.ok || body.ok !== true) throw new Error(body.message ?? `HTTP ${response.status}`)\n setPromptModels(body.models ?? [])\n })\n .catch(error => { setPromptModelsError(error instanceof Error ? error.message : String(error)) })\n .finally(() => { setLoadingPromptModels(false) })\n }}\n >\n {loadingPromptModels ? t('settings.promptModelsLoading') : t('settings.promptModelsFetch')}\n </button>\n </div>\n <div className={css.modelSummary}>\n {state.promptModel.text.trim() !== '' ? (\n <span className={css.modelChip}>\n <span>{state.promptModel.text}</span>\n <button type=\"button\" disabled={disabled} aria-label={`${t('settings.removeModel')}: ${state.promptModel.text}`} onClick={() => { props.edit('promptModel', '') }}>×</button>\n </span>\n ) : null}\n <button type=\"button\" className={css.addModel} disabled={disabled} onClick={() => { setManualPromptModelOpen(open => !open); setEnhancementOpen(true) }}>\n {manualPromptModelOpen ? t('settings.cancelAddModel') : t('settings.addModel')}\n </button>\n </div>\n {manualPromptModelOpen ? (\n <div className={css.manualModelRow}>\n <input className={css.input} value={manualPromptModel} placeholder={t('settings.addPromptModelPlaceholder')} disabled={disabled} onChange={event => { setManualPromptModel(event.target.value) }} />\n <button type=\"button\" className={css.addModel} disabled={disabled || manualPromptModel.trim() === ''} onClick={() => { props.edit('promptModel', manualPromptModel); setManualPromptModel('') }}>{t('settings.addModelConfirm')}</button>\n </div>\n ) : null}\n {promptModels.length > 0 ? (\n <div className={css.modelCandidateList} role=\"radiogroup\" aria-label={t('settings.promptModelsCandidates')}>\n <span className={css.modelCandidateLabel}>{t('settings.promptModelsCandidates')}</span>\n {promptModels.map(candidate => (\n <button\n key={candidate}\n type=\"button\"\n role=\"radio\"\n className={css.modelCandidate}\n aria-checked={state.promptModel.text === candidate}\n data-selected={state.promptModel.text === candidate ? '' : undefined}\n disabled={disabled}\n onClick={() => { props.edit('promptModel', candidate) }}\n >\n {candidate}\n </button>\n ))}\n </div>\n ) : null}\n {promptModelsError !== null ? <p className={css.failed} role=\"status\">{promptModelsError}</p> : null}\n <button type=\"button\" className={css.inlineDisclosure} aria-expanded={promptApiOpen} onClick={() => { setPromptApiOpen(open => !open) }}>\n <span>{t('settings.promptApiAdvanced')}</span>\n <span aria-hidden=\"true\">{promptApiOpen ? '⌃' : '⌄'}</span>\n </button>\n {promptApiOpen ? <div className={css.optionalContent}>\n <ValueField\n id=\"dsh-imagegen-settings-prompt-apiurl\"\n label={t('settings.promptApiUrl')}\n hint={t('settings.promptApiUrlHint')}\n placeholder=\"https://api.openai.com/v1\"\n {...fieldProps}\n {...state.promptApiUrl}\n onEdit={(text) => { props.edit('promptApiUrl', text) }}\n onReset={() => { props.resetField('promptApiUrl') }}\n />\n <ValueField\n id=\"dsh-imagegen-settings-prompt-apikey\"\n label={t('settings.promptApiKey')}\n hint={t('settings.promptApiKeyHint')}\n placeholder=\"sk-…\"\n secret\n {...fieldProps}\n {...state.promptApiKey}\n overridden={false}\n onEdit={(text) => { props.edit('promptApiKey', text) }}\n onReset={() => { props.resetField('promptApiKey') }}\n />\n </div> : null}\n </section> : null}\n\n <button type=\"button\" className={css.disclosure} aria-expanded={moreOpen} onClick={() => { setMoreOpen(open => !open) }}>\n <span>{t('settings.moreOptions')}</span>\n <span aria-hidden=\"true\">{moreOpen ? '⌃' : '⌄'}</span>\n </button>\n {moreOpen ? <div className={css.optionalContent}>\n <BooleanField\n id=\"dsh-imagegen-settings-enabled\"\n label={t('settings.enabled')}\n hint={t('settings.enabledHint')}\n inheritLabel={t('settings.inherit')}\n onLabel={t('settings.on')}\n offLabel={t('settings.off')}\n {...fieldProps}\n {...state.enabled}\n onEdit={(text) => { props.edit('enabled', text) }}\n onReset={() => { props.resetField('enabled') }}\n />\n <BooleanField\n id=\"dsh-imagegen-settings-announce\"\n label={t('settings.announceToAgent')}\n hint={t('settings.announceToAgentHint')}\n inheritLabel={t('settings.inherit')}\n onLabel={t('settings.on')}\n offLabel={t('settings.off')}\n {...fieldProps}\n {...state.announceToAgent}\n onEdit={(text) => { props.edit('announceToAgent', text) }}\n onReset={() => { props.resetField('announceToAgent') }}\n />\n <BooleanField\n id=\"dsh-imagegen-settings-agent-generation\"\n label={t('settings.allowAgentImageGeneration')}\n hint={t('settings.allowAgentImageGenerationHint')}\n inheritLabel={t('settings.inherit')}\n onLabel={t('settings.on')}\n offLabel={t('settings.off')}\n {...fieldProps}\n {...state.allowAgentImageGeneration}\n onEdit={(text) => { props.edit('allowAgentImageGeneration', text) }}\n onReset={() => { props.resetField('allowAgentImageGeneration') }}\n />\n </div> : null}\n <div className={css.footer}>\n {(state.failed || state.channels.failed) ? <p className={css.failed} role=\"status\">{t('settings.saveFailed')}</p> : null}\n <button\n type=\"button\"\n className={css.discard}\n disabled={!state.dirty || state.saving || state.channels.saving}\n onClick={() => { props.discard(); props.channels.discard() }}\n >\n {t('settings.discard')}\n </button>\n <button\n type=\"button\"\n className={css.save}\n disabled={blocked}\n onClick={() => { void props.channels.commit(); void props.save() }}\n >\n {t(!state.saving && !state.channels.saving ? 'settings.save' : 'settings.saving')}\n </button>\n </div>\n </div>\n )\n : null}\n\n {open && editing !== undefined ? (\n <ChannelEditor\n key={editing.id}\n t={t}\n channel={editing}\n keyHeld={state.channels.keySet[editing.id] === true}\n usage={usage}\n otherChannels={channels.filter(channel => channel.id !== editing.id)}\n isDefault={editing.id === state.channels.defaultChannelId}\n writable={state.writable}\n onPatch={(patch) => { replaceChannel(channels, editing.id, patch, props.channels) }}\n onSetModels={(models) => { props.channels.setChannels(channels.map(channel => channel.id === editing.id ? { ...channel, models } : channel)) }}\n onSetKey={(value) => { props.channels.setChannelKey(editing.id, value) }}\n onSetDefault={() => { props.channels.setDefaultChannel(editing.id) }}\n onRemove={() => { props.channels.setChannels(channels.filter(channel => channel.id !== editing.id)); if (editing.id === state.channels.defaultChannelId && channels.length > 1) { const next = channels.find(channel => channel.id !== editing.id); if (next !== undefined) props.channels.setDefaultChannel(next.id) } setEditingId(null) }}\n onClose={() => { setEditingId(null) }}\n />\n ) : null}\n\n </li>\n )\n}\n\n/** Channel row + dialog helpers -------------------------------------------------- */\n\nfunction newChannelDraft(preset: PresetProviderView | undefined): ChannelDraft {\n return {\n id: clientId(),\n preset: preset?.id ?? '',\n name: preset?.name ?? '',\n apiUrl: preset?.apiUrl ?? '',\n models: (preset?.models ?? []).map(model => ({ ...model })),\n }\n}\n\nfunction addCustomChannel(channels: ChannelDraft[], form: ChannelsFormActions, openEditor: (id: string) => void): void {\n const draft = newChannelDraft(undefined)\n form.setChannels([...channels, draft])\n openEditor(draft.id)\n}\n\n/** Patch one field (or models) of one staged channel. */\nfunction replaceChannel(channels: ChannelDraft[], id: string, patch: Partial<ChannelDraft>, form: ChannelsFormActions): void {\n form.setChannels(channels.map(channel => channel.id === id ? { ...channel, ...patch } : channel))\n}\n\nfunction hostOf(apiUrl: string): string {\n try {\n return new URL(apiUrl).hostname\n } catch {\n return apiUrl\n }\n}\n\nfunction clientId(): string {\n const random = typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function' ? crypto.randomUUID() : undefined\n return random ?? `ch-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`\n}\n\n/** Built-in provider picker, expanded inside the settings card. */\nfunction PresetPicker(props: {\n t: (key: ImageGenKey, params?: Record<string, string | number>) => string\n presets: PresetProviderView[]\n error: string | null\n disabled: boolean\n onLoad: () => void\n onPick: (preset: PresetProviderView) => void\n onCustom: () => void\n onClose: () => void\n}) {\n const { t } = props\n const loadedRef = useRef(false)\n useEffect(() => {\n if (loadedRef.current) return\n loadedRef.current = true\n props.onLoad()\n }, [])\n return (\n <section className={css.presetInline} aria-label={t('channels.presetPickerTitle')}>\n <header className={css.presetInlineHeader}>\n <div>\n <h3 className={css.sectionTitle}>{t('channels.presetPickerTitle')}</h3>\n <p className={css.sectionHint}>{t('channels.presetPickerHint')}</p>\n </div>\n <button type=\"button\" className={css.editorClose} aria-label={t('preview.close')} onClick={props.onClose}>×</button>\n </header>\n <div className={css.presetList}>\n {props.presets.map(preset => (\n <button key={preset.id} type=\"button\" className={css.presetRow} disabled={props.disabled} onClick={() => { props.onPick(preset) }}>\n <span className={css.presetName}>{preset.name}</span>\n <span className={css.presetMeta}>{preset.apiUrl} · {t('channels.presetModelsHint', { n: preset.models.length })}</span>\n <span className={css.presetHint}>{preset.hint}</span>\n </button>\n ))}\n <button type=\"button\" className={css.presetRow} data-custom disabled={props.disabled} onClick={props.onCustom}>\n <span className={css.presetName}>+ {t('channels.addCustom')}</span>\n <span className={css.presetHint}>{t('channels.presetCustomHint')}</span>\n </button>\n {props.error !== null ? <p className={css.failed} role=\"status\">{t('channels.presetLoadFailed', { error: props.error })}</p> : null}\n </div>\n </section>\n )\n}\n\n/** Channel editor (modal): key, display name, API URL, model catalog. */\nfunction ChannelEditor(props: {\n t: (key: ImageGenKey, params?: Record<string, string | number>) => string\n channel: ChannelDraft\n keyHeld: boolean\n usage: UsageCounters | null\n otherChannels: ChannelDraft[]\n isDefault: boolean\n writable: boolean\n onPatch: (patch: Partial<ChannelDraft>) => void\n onSetModels: (models: ModelMapping[]) => void\n onSetKey: (value: string | undefined) => void\n onSetDefault: () => void\n onRemove: () => void\n onClose: () => void\n}) {\n const { t, channel } = props\n const [keyDraft, setKeyDraft] = useState('')\n const [candidates, setCandidates] = useState<string[] | null>(null)\n const [detecting, setDetecting] = useState(false)\n const [detectError, setDetectError] = useState<string | null>(null)\n const [manualId, setManualId] = useState('')\n const [removeOpen, setRemoveOpen] = useState(false)\n const [copyFrom, setCopyFrom] = useState('')\n\n const generatedCount = (alias: string): number => {\n if (props.usage === null) return 0\n const channelBucket = props.usage.byChannel[channel.id] ?? props.usage.byChannel[`name:${channel.name}`] ?? {}\n return channelBucket[alias] ?? props.usage.totals[alias] ?? 0\n }\n\n const detect = (): void => {\n setDetecting(true)\n setDetectError(null)\n const payload: Record<string, unknown> = { channelId: channel.id }\n if (channel.apiUrl.trim() !== '') payload.apiUrl = channel.apiUrl.trim()\n if (keyDraft.trim() !== '') payload.apiKey = keyDraft.trim()\n void fetch(IMAGE_MODEL_API.models, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(payload) })\n .then(async response => {\n const body = await response.json() as { ok?: boolean; models?: string[]; message?: string }\n if (!response.ok || body.ok !== true) throw new Error(body.message ?? `HTTP ${response.status}`)\n setCandidates(body.models ?? [])\n })\n .catch(error => { setDetectError(error instanceof Error ? error.message : String(error)) })\n .finally(() => { setDetecting(false) })\n }\n\n // Auto-detect once when the dialog opens with a complete endpoint.\n const autoDetected = useRef(false)\n useEffect(() => {\n if (autoDetected.current) return\n autoDetected.current = true\n if (channel.apiUrl.trim() !== '' && (props.keyHeld || keyDraft.trim() !== '')) detect()\n }, [])\n\n const addManual = (): void => {\n const id = manualId.trim()\n if (id === '') return\n const next = [...channel.models]\n const alias = id\n if (!next.some(model => model.alias === alias)) next.push({ alias, id })\n props.onSetModels(next)\n setManualId('')\n }\n\n const copyFromChannel = (): void => {\n const source = props.otherChannels.find(chance => chance.id === copyFrom)\n if (source === undefined) return\n const merged = [...channel.models]\n for (const model of source.models) {\n const alias = model.alias\n // Copy with a collision suffix so both sources stay selectable.\n let unique = alias\n let suffix = 2\n while (merged.some(entry => entry.alias === unique)) unique = `${alias} (${suffix++})`\n merged.push({ alias: unique, id: model.id })\n }\n props.onSetModels(merged)\n setCopyFrom('')\n }\n\n const onlyKnown = (): void => {\n const known = (candidates ?? []).filter(id => describeModel(id).known)\n const merged = [...channel.models]\n for (const id of known) {\n const alias = id\n if (!merged.some(model => model.alias === alias)) merged.push({ alias, id })\n }\n props.onSetModels(merged)\n }\n\n const knownCount = (candidates ?? []).filter(id => describeModel(id).known).length\n\n return (\n <div className={css.editorBackdrop} role=\"dialog\" aria-modal=\"true\" aria-label={`${t('channels.editorTitle')} · ${channel.name || t('channels.untitled')}`} onClick={props.onClose}>\n <div className={css.editorPanel} onClick={event => { event.stopPropagation() }}>\n <header className={css.editorHeader}>\n <div>\n <h3 className={css.sectionTitle}>{t('channels.editorTitle')} · {channel.name || t('channels.untitled')}</h3>\n <p className={css.sectionHint}>{t('channels.editorSaveNote')}</p>\n </div>\n <button type=\"button\" className={css.editorClose} aria-label={t('preview.close')} onClick={props.onClose}>×</button>\n </header>\n\n <div className={css.editorField}>\n <label className={css.label} htmlFor=\"dsh-imagegen-channel-name\">{t('channels.displayName')}</label>\n <input id=\"dsh-imagegen-channel-name\" className={css.input} value={channel.name} placeholder={t('channels.untitled')} disabled={!props.writable} onChange={event => { props.onPatch({ name: event.target.value }) }} />\n </div>\n <div className={css.editorField}>\n <label className={css.label} htmlFor=\"dsh-imagegen-channel-url\">{t('channels.apiUrl')}</label>\n <input id=\"dsh-imagegen-channel-url\" className={css.input} value={channel.apiUrl} placeholder=\"https://api.example.com/v1\" disabled={!props.writable} onChange={event => { props.onPatch({ apiUrl: event.target.value }) }} />\n </div>\n <div className={css.editorField}>\n <div className={css.head}>\n <label className={css.label} htmlFor=\"dsh-imagegen-channel-key\">{t('channels.apiKey')}</label>\n {props.keyHeld || keyDraft !== ''\n ? (\n <button type=\"button\" className={css.reset} disabled={!props.writable} onClick={() => { setKeyDraft(''); props.onSetKey(undefined) }}>\n {t('channels.keyClear')}\n </button>\n )\n : null}\n </div>\n <input\n id=\"dsh-imagegen-channel-key\"\n className={css.input}\n type=\"password\"\n autoComplete=\"off\"\n value={keyDraft}\n placeholder={props.keyHeld ? t('channels.keyReplaceHint') : t('channels.keyMissingHint')}\n disabled={!props.writable}\n onChange={event => { const value = event.target.value; setKeyDraft(value); props.onSetKey(value === '' ? undefined : value) }}\n />\n </div>\n\n <div className={css.editorDivider} />\n\n <div className={css.editorSectionHeader}>\n <h4 className={css.label}>{t('channels.modelCatalogTitle')}</h4>\n <button type=\"button\" className={css.modelFetch} disabled={!props.writable || detecting} onClick={detect}>\n {detecting ? t('channels.detecting') : t('channels.detect')}\n </button>\n </div>\n {detectError !== null ? <p className={css.failed} role=\"status\">{t('channels.detectFailed', { error: detectError })}</p> : null}\n {candidates !== null && detectError === null ? <p className={css.detectOk} role=\"status\">{t('channels.detectSuccess', { n: candidates.length })}</p> : null}\n\n {channel.models.length === 0\n ? <p className={css.sectionHint}>{t('channels.noModelsHint')}</p>\n : (\n <ul className={css.modelRows}>\n {channel.models.map((model, index) => {\n const entry = describeModel(model.id || model.alias)\n const generated = generatedCount(model.alias)\n return (\n <li key={`${model.alias}-${index}`} className={css.modelRow}>\n <div className={css.modelRowInputs}>\n <input className={css.input} value={model.alias} aria-label={t('channels.modelAliasLabel')} disabled={!props.writable} onChange={event => {\n const next = [...channel.models]\n next[index] = { ...model, alias: event.target.value }\n props.onSetModels(next)\n }} />\n <span className={css.modelArrow}>→</span>\n <input className={css.input} value={model.id} aria-label={t('channels.modelIdLabel')} disabled={!props.writable} onChange={event => {\n const next = [...channel.models]\n next[index] = { ...model, id: event.target.value }\n props.onSetModels(next)\n }} />\n </div>\n <div className={css.modelRowBadges}>\n <span className={css.modelBadge}>{entry.labelZh}{entry.known ? '' : ` · ${t('channels.unknownProtocol')}`}</span>\n {generated > 0 ? <span className={css.modelBadge} data-verified>{t('channels.generated', { n: generated })}</span> : null}\n <button type=\"button\" className={css.modelRowRemove} disabled={!props.writable} aria-label={`${t('channels.removeModel')}: ${model.alias}`} onClick={() => { props.onSetModels(channel.models.filter((_, i) => i !== index)) }}>×</button>\n </div>\n </li>\n )\n })}\n </ul>\n )}\n\n <div className={css.editorTools}>\n <div className={css.manualModelRow}>\n <input className={css.input} value={manualId} placeholder={t('channels.manualAddPlaceholder')} disabled={!props.writable} onChange={event => { setManualId(event.target.value) }} onKeyDown={event => { if (event.key === 'Enter') { event.preventDefault(); addManual() } }} />\n <button type=\"button\" className={css.addModel} disabled={!props.writable || manualId.trim() === ''} onClick={addManual}>{t('channels.addModelConfirm')}</button>\n </div>\n {props.otherChannels.length > 0 ? (\n <div className={css.manualModelRow}>\n <select className={css.modelChoices} value={copyFrom} disabled={!props.writable} onChange={event => { setCopyFrom(event.target.value) }} aria-label={t('channels.copyFrom')}>\n <option value=\"\">{t('channels.copyFrom')}</option>\n {props.otherChannels.map(other => (\n <option key={other.id} value={other.id}>{other.name || t('channels.untitled')}</option>\n ))}\n </select>\n <button type=\"button\" className={css.addModel} disabled={!props.writable || copyFrom === ''} onClick={copyFromChannel}>{t('channels.copyApply')}</button>\n </div>\n ) : null}\n </div>\n\n {candidates !== null && candidates.length > 0 ? (\n <div className={css.modelCandidateList}>\n <span className={css.modelCandidateLabel}>\n {t('channels.candidatesTitle')}\n <button type=\"button\" className={css.inlineDisclosure} disabled={!props.writable || knownCount === 0} onClick={onlyKnown}>{t('channels.candidatesQuick')}</button>\n </span>\n {candidates.map(candidate => {\n const selected = channel.models.some(model => model.alias === candidate)\n const entry = describeModel(candidate)\n return (\n <label key={candidate} className={css.modelCandidate} data-selected={selected ? '' : undefined}>\n <input type=\"checkbox\" checked={selected} disabled={!props.writable} onChange={() => {\n const merged = selected\n ? channel.models.filter(model => model.alias !== candidate)\n : [...channel.models, { alias: candidate, id: candidate }]\n props.onSetModels(merged)\n }} />\n <span>{candidate}</span>\n {!entry.known ? <span className={css.modelBadge} data-warn>{t('channels.unknownProtocol')}</span> : <span className={css.modelBadge}>{entry.labelZh}</span>}\n </label>\n )\n })}\n </div>\n ) : null}\n\n <div className={css.editorDivider} />\n\n <div className={css.editorFooter}>\n {props.isDefault ? <span className={css.channelBadge} data-default>{t('channels.defaultLabel')}</span> : (\n <button type=\"button\" className={css.inlineDisclosure} disabled={!props.writable} onClick={props.onSetDefault}>{t('channels.setDefault')}</button>\n )}\n <span className={css.spacer} />\n {removeOpen\n ? (\n <>\n <button type=\"button\" className={css.channelDanger} disabled={!props.writable} onClick={props.onRemove}>{t('channels.confirm')}</button>\n <button type=\"button\" className={css.channelAction} onClick={() => { setRemoveOpen(false) }}>{t('channels.cancel')}</button>\n </>\n )\n : (\n <button type=\"button\" className={css.channelAction} data-danger onClick={() => { setRemoveOpen(true) }}>{t('channels.deleteThisChannel')}</button>\n )}\n </div>\n </div>\n </div>\n )\n}\n\n/** Props every field control needs regardless of its value type. */\ninterface FieldProps {\n /** Stable id associating the label with its control. */\n id: string\n /** Visible label. */\n label: string\n /** One-line explanation rendered under the control. */\n hint: string\n /** Draft text this control renders. */\n text: string\n /** True when saving would leave a user-layer entry for this field. */\n overridden: boolean\n /** True when the draft is not a value this field accepts. */\n invalid: boolean\n /** Copy for the overridden badge. */\n overriddenLabel: string\n /** Copy for the reset control. */\n resetLabel: string\n /** Copy shown in place of the hint while the draft is invalid. */\n invalidLabel: string\n /** Disables every control (read-only document, or an unavailable namespace). */\n disabled: boolean\n /** Stage draft text. */\n onEdit: (text: string) => void\n /** Stage a clear so the field re-inherits the composition layer. */\n onReset: () => void\n}\n\n/** A staged value field; `secret` renders a password control. */\nfunction ValueField(props: FieldProps & {\n /** Render a password control. */\n secret?: boolean\n /** Placeholder shown while the draft is empty. */\n placeholder?: string\n /** Label of the dedicated clear control (secret fields). */\n clearLabel?: string\n /** Stage a clear of the stored secret. */\n onClear?: () => void\n /** Whether a stored secret exists (enables the clear control). */\n canClear?: boolean\n}) {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden\n ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button\n type=\"button\"\n className={css.reset}\n disabled={props.disabled}\n onClick={props.onReset}\n >\n {props.resetLabel}\n </button>\n </span>\n )\n : null}\n {props.secret === true && props.canClear === true\n ? (\n <button\n type=\"button\"\n className={css.reset}\n disabled={props.disabled}\n onClick={props.onClear}\n >\n {props.clearLabel ?? props.resetLabel}\n </button>\n )\n : null}\n </div>\n <input\n id={props.id}\n className={props.invalid ? css.inputInvalid : css.input}\n type={props.secret === true ? 'password' : 'text'}\n autoComplete={props.secret === true ? 'off' : undefined}\n {...props.invalid ? { 'aria-invalid': true } : {}}\n value={props.text}\n placeholder={props.placeholder ?? ''}\n disabled={props.disabled}\n onChange={(event) => { props.onEdit(event.target.value) }}\n />\n <p className={props.invalid ? css.invalid : css.hint}>\n {props.invalid ? props.invalidLabel : props.hint}\n </p>\n </div>\n )\n}\n\n/** A staged boolean field: 继承 / 开 / 关. */\nfunction BooleanField(props: FieldProps & {\n /** Copy for the inherit option. */\n inheritLabel: string\n /** Copy for the on option. */\n onLabel: string\n /** Copy for the off option. */\n offLabel: string\n}) {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden\n ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button\n type=\"button\"\n className={css.reset}\n disabled={props.disabled}\n onClick={props.onReset}\n >\n {props.resetLabel}\n </button>\n </span>\n )\n : null}\n </div>\n <select\n id={props.id}\n className={css.select}\n value={props.text}\n disabled={props.disabled}\n onChange={(event) => { props.onEdit(event.target.value) }}\n >\n <option value=\"\">{props.inheritLabel}</option>\n <option value=\"true\">{props.onLabel}</option>\n <option value=\"false\">{props.offLabel}</option>\n </select>\n <p className={css.hint}>{props.hint}</p>\n </div>\n )\n}\n","/** Inline renderer for image-generation tool-result attachments. */\n\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'\nimport type { ClientContext, SessionId, ToolCallBlock } from '@deepseek-ai/dsh-client-runtime/client'\nimport { useEffect, useMemo, useState } from 'react'\nimport { AGENT_IMAGE_API } from '../protocol.ts'\nimport css from './image-toolview.module.css'\n\n/** Owner props supplied by the host's keyed tool-call slot. */\nexport interface ImageToolViewOwnerProps {\n callId: string\n toolName: string\n block: ToolCallBlock\n cwd?: string\n home?: string\n openFile: (path: string) => void\n inspect?: () => void\n}\n\ninterface LoadedImage {\n ref: ImageAttachmentRef\n src: string\n}\n\ninterface ImageToolViewProps extends ImageToolViewOwnerProps {\n sessionId: SessionId\n}\n\nfunction isSettled(block: ToolCallBlock): block is Extract<ToolCallBlock, { kind: 'tool-result' }> {\n return 'kind' in block\n}\n\nfunction imageRefsOf(block: ToolCallBlock): ImageAttachmentRef[] {\n if (!isSettled(block)) return []\n const resultContent = block.resultView?.card === 'generic' ? block.resultView.content ?? [] : []\n return [...block.content, ...resultContent]\n .flatMap(content => content.type === 'image' ? [content.attachment] : [])\n}\n\nfunction textOf(block: ToolCallBlock): string {\n if (!isSettled(block)) return ''\n return block.content\n .filter(content => content.type === 'text')\n .map(content => content.text)\n .join('\\n')\n}\n\nfunction resultInfo(block: ToolCallBlock): { status: string; message: string } {\n if (!isSettled(block)) return { status: 'running', message: '正在生成图片…' }\n const text = textOf(block)\n try {\n const parsed = JSON.parse(text) as { status?: unknown; message?: unknown }\n return {\n status: typeof parsed.status === 'string' ? parsed.status : block.isError ? 'failed' : 'completed',\n message: typeof parsed.message === 'string' ? parsed.message : '',\n }\n } catch {\n return { status: block.isError ? 'failed' : 'completed', message: text }\n }\n}\n\nfunction statusLabel(status: string): string {\n if (status === 'running' || status === 'queued') return '生成中'\n if (status === 'failed') return '生成失败'\n if (status === 'cancelled') return '已取消'\n return '图片结果'\n}\n\nfunction useAttachmentImages(\n sessionId: SessionId,\n refs: ImageAttachmentRef[],\n load: (sessionId: SessionId, ref: ImageAttachmentRef) => Promise<string>,\n): { images: LoadedImage[]; error: string | null } {\n const key = useMemo(() => refs.map(ref => String(ref.attachmentId)).join('|'), [refs])\n const [images, setImages] = useState<LoadedImage[]>([])\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n let disposed = false\n const urls: string[] = []\n const revoke = (): void => {\n for (const url of urls) URL.revokeObjectURL(url)\n urls.length = 0\n }\n\n setImages([])\n setError(null)\n if (refs.length === 0) return () => { /* no attachments to clean up */ }\n\n void Promise.all(refs.map(async ref => {\n const src = await load(sessionId, ref)\n urls.push(src)\n return { ref, src }\n }))\n .then(next => {\n if (!disposed) setImages(next)\n })\n .catch(errorValue => {\n revoke()\n if (!disposed) setError(errorValue instanceof Error ? errorValue.message : String(errorValue))\n })\n\n return () => {\n disposed = true\n revoke()\n }\n }, [key, load, refs, sessionId])\n\n return { images, error }\n}\n\n/** Register the inline image result view for all image-generation result tools. */\nexport function registerImageToolviews(ctx: ClientContext): void {\n const load = async (_sessionId: SessionId, ref: ImageAttachmentRef): Promise<string> => {\n // Tool-result images intentionally do not occur in model-visible session\n // content, so session.readAttachment() rejects them. The plugin route\n // reads the same durable attachment after validating the complete ref.\n const query = new URLSearchParams({\n attachment_id: String(ref.attachmentId),\n media_type: ref.mediaType,\n bytes: String(ref.bytes),\n width: String(ref.width),\n height: String(ref.height),\n })\n const response = await fetch(`${AGENT_IMAGE_API}?${query.toString()}`)\n if (!response.ok) throw new Error(`无法读取图片附件(HTTP ${response.status})。`)\n const blob = await response.blob()\n return URL.createObjectURL(blob)\n }\n\n const ImageToolView = (props: ImageToolViewProps): React.JSX.Element => {\n const refs = useMemo(() => imageRefsOf(props.block), [props.block])\n const { status, message } = resultInfo(props.block)\n const { images, error } = useAttachmentImages(props.sessionId, refs, load)\n\n return <section className={css.root} data-state={status} data-tool={props.toolName}>\n <header className={css.header}>\n <span className={css.icon} aria-hidden=\"true\">▧</span>\n <strong>{props.toolName}</strong>\n <span className={css.status}>{statusLabel(status)}</span>\n </header>\n {message !== '' && <p className={css.message}>{message}</p>}\n {images.length > 0 && <div className={css.images}>\n {images.map(image => <a\n className={css.imageLink}\n href={image.src}\n key={String(image.ref.attachmentId)}\n rel=\"noreferrer\"\n target=\"_blank\"\n title=\"打开原图\"\n >\n <img className={css.image} src={image.src} alt={image.ref.name ?? '生成图片'} />\n </a>)}\n </div>}\n {refs.length > 0 && images.length === 0 && error === null && <p className={css.loading}>正在加载图片…</p>}\n {error !== null && <p className={css.error}>{error}</p>}\n </section>\n }\n\n ctx.slots.inject('tool.call.toolview', function* () {\n for (const key of ['generate_image', 'edit_image', 'get_image_generation_task']) {\n yield ctx.slots.register({ name: 'tool.call.toolview', key }, ImageToolView)\n }\n })\n}\n","/**\r\n * Browser-half entry for the dsh-imagegen plugin — runs inside the dsh web\r\n * GUI.\r\n *\r\n * Registers the dsh-imagegen locale dictionaries, binds the plugin's own\r\n * settings scope (its bridge routes serve the namespace the official rc.6\r\n * allowlist would refuse), registers the settings card into the Web UI plugin\r\n * group slot, and mounts the two DOM surfaces: the sidebar entry row (toggles\r\n * the panel) and the generation studio in the center column. Failure policy:\r\n * DOM mounting problems are logged, never thrown — the web shell fails the\r\n * whole boot when a plugin apply throws, and an external plugin must not take\r\n * the GUI down.\r\n */\r\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\r\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'\r\n// Type-only: pulls the locale plugin's Context merge (ctx.locale).\r\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\r\n// Type-only: pulls the LocaleNamespaceMap merge table.\r\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\r\nimport { ImageGenApi } from './api.ts'\r\nimport { ImageGenController } from './controller.ts'\r\nimport { tt } from './helpers.ts'\r\nimport { en, zh, type ImageGenKey } from './locales.ts'\r\nimport { mountPanel } from './mount.tsx'\r\nimport { mountSidebarEntry } from './sidebar-entry.ts'\r\nimport { ImageGenSettingsCard, ImageGenSettingsCardController } from './SettingsCard.tsx'\nimport { bindImageGenScope, type ImageGenScope } from './settings-scope.ts'\nimport { registerImageToolviews, type ImageToolViewOwnerProps } from './image-toolview.tsx'\n\r\n/** Locale namespace this plugin owns. */\r\nconst NS = 'dsh-imagegen'\r\n\r\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\r\n interface LocaleNamespaceMap {\r\n /** dsh-imagegen surface copy. */\r\n 'dsh-imagegen': ImageGenKey\r\n }\r\n\r\n interface SlotMap {\n /**\r\n * The official plugin-configuration slot the Settings → Plugins →\r\n * Configurable tab declares and renders. This card registers there as its\r\n * own standalone card — independent of the dsh-web-ui family group — so\r\n * this plugin never reads as part of that family. Spelled here with the\r\n * same shape so this package can register without depending on the\r\n * sibling UI package.\r\n */\r\n 'settings.plugin.item': { kind: 'keyed'; scope: 'root'; owner: ImageGenPluginItemOwnerProps }\n /** Image-generation results render their durable image blocks inline. */\n 'tool.call.toolview': { kind: 'keyed'; scope: 'session'; owner: ImageToolViewOwnerProps }\n }\n}\n\r\n/** Owner share of a plugin card (the section supplies nothing). */\r\nexport interface ImageGenPluginItemOwnerProps {\r\n /** Marker field: card owner props are intentionally empty. */\r\n children?: never\r\n}\r\n\r\n/** Required services (fiber inject waiting — the runtime must be up first). */\r\nexport const inject = ['slots', 'locale', 'connection', 'sessions']\n\r\n/**\r\n * Mount the studio, its sidebar entry, and the settings card.\r\n * @param ctx - client root context (services: slots, locale, connection).\r\n */\r\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-imagegen: dictionaries')\n registerImageToolviews(ctx)\n\r\n const connection = ctx.get('connection') as ConnectionHandle | undefined\r\n const loopback = connection?.isLoopback === true\r\n // The bridge routes are loopback-fenced; remote browsers get an unavailable\r\n // scope (the card explains the gap) instead of failing fetches.\r\n const scope: ImageGenScope = bindImageGenScope(loopback\r\n ? (input, init) => fetch(input, init)\r\n : () => { throw new Error('settings bridge is loopback-only') })\r\n\r\n // Re-read the scope whenever the connection resets (same invalidation the\r\n // official settings binder wires).\r\n ctx.effect(() => {\r\n const disposers = [\r\n ctx.on('connection/reset', () => { void scope.load() }),\r\n ]\r\n return () => { for (const dispose of disposers) dispose() }\r\n }, 'dsh-imagegen: settings scope invalidation')\r\n\r\n // Plugin configuration card: one staged form over the `dsh-imagegen` scope,\r\n // registered into the official plugin-configuration slot (Settings →\r\n // Plugins → Configurable) as a standalone card.\r\n const settingsCard = new ImageGenSettingsCardController(scope)\r\n ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({\r\n name: 'settings.plugin.item',\r\n key: 'dsh-imagegen',\r\n locale: NS,\r\n inject: () => settingsCard.inject(),\r\n }, ImageGenSettingsCard))\r\n\r\n // The sidebar entry and studio mount once the settings scope settles; while\r\n // the scope is still loading, the composition default is unknown, so nothing\r\n // mounts yet. Only an unavailable scope falls back to the default (enabled).\r\n let uiDisposer: (() => void) | undefined\r\n const mountUi = (): void => {\r\n if (uiDisposer !== undefined) return\r\n const controller = new ImageGenController()\r\n const api = new ImageGenApi()\r\n const disposers: Array<() => void> = []\r\n try {\r\n disposers.push(mountSidebarEntry(controller, tt('entry.label'), tt('entry.tooltip')))\r\n disposers.push(mountPanel(controller, api, scope))\r\n } catch (error) {\r\n // DOM failures degrade the studio, never the GUI.\r\n console.warn('[dsh-imagegen] mount failed:', error)\r\n }\r\n uiDisposer = () => {\r\n for (const dispose of disposers.splice(0)) dispose()\r\n uiDisposer = undefined\r\n }\r\n }\r\n const syncEnabled = (): void => {\r\n const snapshot = scope.getSnapshot()\r\n const enabled = snapshot.status === 'ready'\r\n ? snapshot.value?.enabled ?? true\r\n : snapshot.status === 'unavailable'\r\n if (enabled) mountUi()\r\n else uiDisposer?.()\r\n }\r\n scope.subscribe(syncEnabled)\r\n syncEnabled()\r\n}\r\n"],"mappings":"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"}