dsh-audiogen 0.2.0 → 0.3.2
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 +1101 -573
- package/lib/client.js.map +1 -1
- package/lib/index.js +528 -125
- package/package.json +1 -1
- package/skills/tts/SKILL.md +42 -4
- package/src/agent-audio-tools.ts +94 -7
- package/src/audio-engine.ts +215 -29
- package/src/audio-models.ts +132 -24
- package/src/audio-presets.ts +27 -33
- package/src/audio-store.ts +2 -0
- package/src/client/AudioGenPanel.tsx +140 -36
- package/src/client/SettingsCard.tsx +520 -176
- package/src/client/audio-panel.module.css +36 -0
- package/src/client/locales.ts +88 -18
- package/src/client/settings-card.module.css +424 -607
- package/src/protocol.ts +44 -2
- package/src/routes.ts +49 -4
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["css","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/settings-scope.ts","../src/client/AudioGenPanel.tsx","../src/client/mount.tsx","../src/client/sidebar-entry.ts","../src/client/settings-form.ts","../src/client/channels-form.ts","../src/client/SettingsCard.tsx","../src/client/audio-toolview.tsx","../src/client/index.ts"],"sourcesContent":["/**\n * Wire contract shared by the host and client halves of dsh-audiogen:\n * settings namespace, route paths, generate payload/result shapes.\n * Pure types and constants — safe for the client bundle to inline.\n */\n\n/** Settings namespace this plugin owns (host settings seam + bridge). */\nexport const AUDIOGEN_SETTINGS_NAMESPACE = 'dsh-audiogen'\n\n/** Published package version shared by the host updater and the client UI. */\nexport const PLUGIN_VERSION = '0.2.0'\n\n/** Same-origin route family (loopback-only, mirroring dsh-imagegen). */\nexport const SETTINGS_API = {\n describe: '/api/dsh-audiogen/settings/describe',\n mutate: '/api/dsh-audiogen/settings/mutate',\n} as const\n\n/** The audio-generation proxy route. */\nexport const GENERATE_API = '/api/dsh-audiogen/generate' as const\n\n/** Host-mediated built-in provider catalog (channels the user can instantiate). */\nexport const PRESETS_API = '/api/dsh-audiogen/presets' as const\n\n/** Host-mediated model/voice discovery endpoint. */\nexport const MODEL_API = {\n discover: '/api/dsh-audiogen/models/discover',\n} as const\n\n/** Loopback-only audio file reader for panel/tool-result previews. */\nexport const AUDIO_API = {\n file: '/api/dsh-audiogen/audio',\n} as const\n\n/** Host-persisted generation history routes. */\nexport const HISTORY_API = {\n list: '/api/dsh-audiogen/history/list',\n append: '/api/dsh-audiogen/history/append',\n remove: '/api/dsh-audiogen/history/remove',\n clear: '/api/dsh-audiogen/history/clear',\n audio: '/api/dsh-audiogen/history/audio',\n} as const\n\n/** Maximum number of history entries retained host-side (oldest evicted). */\nexport const HISTORY_MAX = 50\n\n/** Audio generation modes. */\nexport type AudioMode = 'tts' | 'music' | 'sfx'\n\n/** The capability category of an audio model/voice. */\nexport type AudioModelCategory =\n | 'tts'\n | 'music'\n | 'sfx'\n | 'voice_design'\n | 'voice_clone'\n\n/** One model mapping in a channel's catalog: display alias → upstream id. */\nexport interface ModelMapping {\n /** User-facing model/voice name (defaults to the upstream id). */\n alias: string\n /** Upstream model or voice id sent to the provider. */\n id: string\n /** Optional capability category, used by the UI to group model lists. */\n category?: AudioModelCategory\n}\n\n/** A model/voice discovered from a vendor endpoint (not yet persisted). */\nexport interface DiscoveredAudioModel extends ModelMapping {\n /** Optional human-readable description from the vendor. */\n description?: string\n}\n\n/**\n * One configured audio channel (provider). Secrets never live here — the API\n * key is stored at `channelSecrets.<channelId>`.\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, panel, and Agent guidance. */\n name: string\n /** Provider base URL. */\n apiUrl: string\n /** The channel's model/voice 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\n/** A client → host generate request. */\nexport interface GenerateAudioRequest {\n mode: AudioMode\n /** User-facing model/voice alias; host maps to upstream id. */\n model: string\n /** TTS text or music/sfx prompt. */\n prompt: string\n /** Optional voice alias for TTS. */\n voice?: string\n /** Optional speaking rate / speed multiplier. */\n speed?: number\n /** Requested duration in seconds (music/sfx). */\n duration?: number\n /** Output format, e.g. mp3, wav, pcm. */\n format?: string\n /** Channel this request targets (host falls back to default). */\n channelId?: string\n /** Channel display name snapshot (host-filled). */\n channel?: string\n /** Upstream model id actually sent (host-filled from alias mapping). */\n upstream?: string\n}\n\n/** One generated audio, normalized host-side to base64. */\nexport interface GeneratedAudio {\n /** Raw base64 payload (no data: prefix). */\n b64: string\n /** MIME type, e.g. audio/mpeg. */\n mime: string\n /** Exact encoded byte length. */\n bytes: number\n /** Optional duration in seconds when the API reports one. */\n duration?: number\n /** Same-origin URL served by the host ('' when unavailable). */\n url: string\n /** Stable audio id / file name. */\n id: string\n}\n\n/** Successful generate outcome. */\nexport interface GenerateAudioResult {\n outputs: GeneratedAudio[]\n /** Updated host-persisted history, when returned. */\n history?: HistoryEntry[]\n /** Persistence failure after audio was generated. */\n historyError?: string\n}\n\n/** One audio reference as the browser consumes it. */\nexport interface HistoryAudioRef {\n /** Same-origin URL. */\n url: string\n /** MIME type, e.g. audio/mpeg. */\n mime: string\n /** Duration in seconds when known. */\n duration?: number\n}\n\n/** A saved generation as the browser consumes it. */\nexport interface HistoryEntry {\n id: string\n createdAt: number\n mode: AudioMode\n model: string\n prompt: string\n voice?: string\n speed?: number\n duration?: number\n format?: string\n audio: HistoryAudioRef[]\n channelId?: string\n channel?: string\n}\n\n/** A history entry the client submits for persistence (audio still carries base64). */\nexport interface HistoryEntryInput {\n id: string\n createdAt: number\n mode: AudioMode\n model: string\n prompt: string\n voice?: string\n speed?: number\n duration?: number\n format?: string\n audio: GeneratedAudio[]\n channelId?: string\n channel?: string\n}\n\n/** The plugin settings fields edited by the settings card and panel. */\nexport interface AudiogenConfig {\n enabled?: boolean\n announceToAgent?: boolean\n allowAgentAudioGeneration?: boolean\n channels?: ChannelConfig[]\n channelSecrets?: Record<string, string>\n defaultChannelId?: string\n /** Optional default voice/model alias for quick generation. */\n defaultModel?: string\n}\n","/**\n * Browser-side API client for the audio generation and history routes.\n */\n\nimport { GENERATE_API, HISTORY_API, type GenerateAudioRequest, type GeneratedAudio, type HistoryEntry } from '../protocol.ts'\n\nexport interface GenerateResponse {\n ok: boolean\n outputs?: GeneratedAudio[]\n history?: HistoryEntry[]\n historyError?: string\n code?: string\n message?: string\n}\n\nexport class AudiogenApi {\n async generate(request: GenerateAudioRequest): Promise<GenerateResponse> {\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 response.json() as GenerateResponse\n return body\n }\n\n async history(): Promise<HistoryEntry[]> {\n const response = await fetch(HISTORY_API.list, { method: 'POST' })\n const body = await response.json() as { ok?: boolean; history?: HistoryEntry[] }\n return body.ok === true ? (body.history ?? []) : []\n }\n\n async clearHistory(): Promise<void> {\n await fetch(HISTORY_API.clear, { method: 'POST' })\n }\n}\n","/**\n * Audio panel controller: the single owner of the panel's open/closed state.\n * Framework-free so the DOM mounts and the React panel share one tiny\n * subscription surface.\n */\n\nexport interface AudioGenControllerSnapshot {\n panelOpen: boolean\n}\n\nexport class AudioGenController {\n private panelOpen = false\n private listeners = new Set<() => void>()\n\n getSnapshot(): AudioGenControllerSnapshot {\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-audiogen surface copy: zh is the key source, en mirrors every key.\n */\n\nexport const zh = {\n 'entry.label': 'AI 音频',\n 'entry.tooltip': 'AI 音频面板(TTS / 音乐 / 音效)',\n 'panel.title': 'AI 音频',\n 'mode.tts': '文本转语音',\n 'mode.music': '音乐生成',\n 'mode.sfx': '音效生成',\n 'prompt.placeholder': '输入要朗读的文本,或描述想生成的音乐 / 音效…',\n 'prompt.required': '请输入文本或提示词',\n 'model.label': '模型 / 音色',\n 'voice.label': '音色',\n 'speed.label': '语速',\n 'duration.label': '时长(秒)',\n 'format.label': '输出格式',\n 'generate': '开始生成',\n 'generating': '生成中…',\n 'download': '下载',\n 'result.empty': '生成结果将显示在这里',\n 'result.done': '生成完成,共 {count} 段音频',\n 'history.title': '历史记录',\n 'history.empty': '暂无历史记录',\n 'config.missing': '尚未配置音频 API:请前往「设置 → 插件 → AI 音频」添加渠道。',\n 'config.disabled': '插件已停用,请在设置中重新启用。',\n 'settings.title': 'AI 音频(dsh-audiogen)',\n 'settings.description': '配置多厂商音频生成 API 地址与密钥',\n 'settings.collapse': '收起',\n 'settings.expand': '展开',\n 'settings.enabled': '启用插件',\n 'settings.announceToAgent': '向 Agent 播报本插件',\n 'settings.allowAgentAudio': '允许 Agent 调用音频生成',\n 'settings.save': '保存',\n 'settings.saving': '保存中…',\n 'settings.discard': '放弃修改',\n 'settings.unsaved': '有未保存的修改',\n 'settings.readOnly': '当前设置为只读。',\n 'channels.title': '音频渠道',\n 'channels.hint': '每个渠道是一个独立的音频厂商/API 端点,可配置多个。',\n 'channels.empty': '还没有渠道。',\n 'channels.addProvider': '+ 添加预置厂商',\n 'channels.addCustom': '+ 添加自定义渠道',\n 'channels.edit': '编辑',\n 'channels.delete': '删除',\n 'channels.confirm': '确认删除',\n 'channels.cancel': '取消',\n 'channels.keySet': '已填密钥',\n 'channels.keyMissing': '未填密钥',\n 'channels.modelCount': '{n} 个模型/音色',\n 'channels.noModels': '未配置模型',\n 'channels.statusReady': '可用',\n 'channels.statusIncomplete': '未完成',\n 'channels.untitled': '未命名渠道',\n 'channel.name': '名称',\n 'channel.apiUrl': 'API 地址',\n 'channel.apiKey': 'API 密钥',\n 'channel.apiKeyHint': '留空则保持当前密钥;输入新值可更换。',\n 'channel.models': '模型 / 音色(每行一个:别名=上游ID)',\n 'channel.modelsHint': '每行格式:别名=上游ID,可加 @分类(tts/music/sfx/voice_design/voice_clone);例如 tts-1=tts-1 @tts 或 Rachel=21m00Tcm4TlvDq8ikWAM @tts',\n 'channel.default': '设为默认',\n 'channel.cancel': '取消',\n 'channel.save': '保存渠道',\n 'presets.title': '预置厂商',\n 'presets.custom': '自定义渠道',\n} as const\n\nexport type AudioGenKey = keyof typeof zh\n\nexport const en: Record<AudioGenKey, string> = {\n 'entry.label': 'AI Audio',\n 'entry.tooltip': 'AI audio panel (TTS / music / SFX)',\n 'panel.title': 'AI Audio',\n 'mode.tts': 'Text to speech',\n 'mode.music': 'Music',\n 'mode.sfx': 'Sound effects',\n 'prompt.placeholder': 'Text to speak, or a description of the music / sound effect…',\n 'prompt.required': 'Prompt or text is required',\n 'model.label': 'Model / voice',\n 'voice.label': 'Voice',\n 'speed.label': 'Speed',\n 'duration.label': 'Duration (s)',\n 'format.label': 'Format',\n 'generate': 'Generate',\n 'generating': 'Generating…',\n 'download': 'Download',\n 'result.empty': 'Generated audio will appear here.',\n 'result.done': 'Done, {count} audio file(s).',\n 'history.title': 'History',\n 'history.empty': 'No audio history yet.',\n 'config.missing': 'No audio API configured. Open Settings > Plugins > AI Audio and add a channel.',\n 'config.disabled': 'The plugin is disabled. Enable it in Settings.',\n 'settings.title': 'AI Audio (dsh-audiogen)',\n 'settings.description': 'Configure multi-vendor audio generation endpoints and keys',\n 'settings.collapse': 'Collapse',\n 'settings.expand': 'Expand',\n 'settings.enabled': 'Enable plugin',\n 'settings.announceToAgent': 'Announce this plugin to agents',\n 'settings.allowAgentAudio': 'Allow agents to generate audio',\n 'settings.save': 'Save',\n 'settings.saving': 'Saving…',\n 'settings.discard': 'Discard',\n 'settings.unsaved': 'Unsaved changes',\n 'settings.readOnly': 'Settings are read-only.',\n 'channels.title': 'Audio channels',\n 'channels.hint': 'Each channel is an independent audio vendor/API endpoint.',\n 'channels.empty': 'No channels yet.',\n 'channels.addProvider': '+ Add preset vendor',\n 'channels.addCustom': '+ Add custom channel',\n 'channels.edit': 'Edit',\n 'channels.delete': 'Delete',\n 'channels.confirm': 'Confirm delete',\n 'channels.cancel': 'Cancel',\n 'channels.keySet': 'Key set',\n 'channels.keyMissing': 'No key',\n 'channels.modelCount': '{n} model(s)/voice(s)',\n 'channels.noModels': 'No models configured',\n 'channels.statusReady': 'Ready',\n 'channels.statusIncomplete': 'Incomplete',\n 'channels.untitled': 'Untitled channel',\n 'channel.name': 'Name',\n 'channel.apiUrl': 'API URL',\n 'channel.apiKey': 'API key',\n 'channel.apiKeyHint': 'Leave blank to keep the current key.',\n 'channel.models': 'Models / voices (one per line: alias=upstreamId)',\n 'channel.modelsHint': 'One per line: alias=upstreamId, optional @category (tts/music/sfx/voice_design/voice_clone); e.g. tts-1=tts-1 @tts or Rachel=21m00Tcm4TlvDq8ikWAM @tts',\n 'channel.default': 'Set default',\n 'channel.cancel': 'Cancel',\n 'channel.save': 'Save channel',\n 'presets.title': 'Preset vendors',\n 'presets.custom': 'Custom channel',\n}\n","/**\n * Shared panel helpers: active-dictionary pick and a small error extractor.\n */\n\nimport { en, zh, type AudioGenKey } from './locales.ts'\n\nexport type TranslateValues = Record<string, string | number>\n\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\nexport function tt(key: AudioGenKey, 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\nexport function errorMessage(error: unknown): string {\n if (error instanceof Error) return error.message\n return String(error)\n}\n","/**\n * Browser-side settings scope for the dsh-audiogen namespace, served by the\n * plugin's own loopback bridge routes (/api/dsh-audiogen/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 AudioModelCategory, type ChannelConfig } from '../protocol.ts'\n\n/** The fields this plugin's settings card edits. */\nexport interface AudiogenConfig {\n enabled?: boolean\n announceToAgent?: boolean\n allowAgentAudioGeneration?: 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 defaultModel?: 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 AudiogenScope extends SettingsScope<AudiogenConfig> {\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-audiogen 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 bindAudiogenScope(fetchFn: typeof fetch = fetch): AudiogenScope {\n const controller = new BridgeScopeController<AudiogenConfig>(createBridgeApi(fetchFn).settings, {\n namespace: 'dsh-audiogen',\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 audioModelOptions(config: AudiogenConfig | undefined): {\n models: Array<{ alias: string; category?: AudioModelCategory }>\n defaultChannelId?: string\n} {\n const channels = config?.channels ?? []\n if (channels.length === 0) {\n return { models: [] }\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: Array<{ alias: string; category?: AudioModelCategory }> = []\n const seen = new Set<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 === '' || seen.has(model.alias)) continue\n seen.add(model.alias)\n models.push({ alias: model.alias, ...(model.category === undefined ? {} : { category: model.category }) })\n }\n }\n return models.length > 0 ? { models, defaultChannelId: defaultId } : { models: [], defaultChannelId: defaultId }\n}\n","/**\n * The AI 音频 panel: a compact audio-generation studio.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport type { AudiogenApi } from './api.ts'\nimport type { AudiogenScope } from './settings-scope.ts'\nimport { audioModelOptions } from './settings-scope.ts'\nimport { tt } from './helpers.ts'\nimport { GENERATE_API, HISTORY_API, type AudioMode, type GeneratedAudio, type HistoryEntry } from '../protocol.ts'\nimport css from './audio-panel.module.css'\n\nfunction useConfig(scope: AudiogenScope) {\n const [value, setValue] = useState(scope.getSnapshot().value)\n useEffect(() => scope.subscribe(() => { setValue(scope.getSnapshot().value) }), [scope])\n return value\n}\n\nfunction useHistory(): { entries: HistoryEntry[]; reload: () => void; clear: () => void } {\n const [entries, setEntries] = useState<HistoryEntry[]>([])\n const reload = (): void => {\n void fetch(HISTORY_API.list, { method: 'POST' })\n .then(async response => {\n const body = await response.json() as { ok?: boolean; history?: HistoryEntry[] }\n if (body.ok === true) setEntries(body.history ?? [])\n })\n .catch(() => { /* history is best-effort */ })\n }\n useEffect(() => { reload() }, [])\n const clear = (): void => {\n void fetch(HISTORY_API.clear, { method: 'POST' })\n .then(() => reload())\n .catch(() => { /* best-effort */ })\n }\n return { entries, reload, clear }\n}\n\nfunction dataUrlOf(audio: GeneratedAudio): string {\n return `data:${audio.mime};base64,${audio.b64}`\n}\n\nexport function AudioGenPanel(props: { api: AudiogenApi; scope: AudiogenScope }) {\n const { api, scope } = props\n const config = useConfig(scope)\n const enabled = config?.enabled ?? true\n const modelOptions = audioModelOptions(config)\n const channels = config?.channels ?? []\n const connected = enabled && channels.some(channel => {\n const keyHeld = scope.getSecretSetSnapshot(`channelSecrets.${channel.id}`)\n return channel.apiUrl.trim() !== '' && keyHeld && channel.models.length > 0\n })\n\n const [mode, setMode] = useState<AudioMode>('tts')\n const [prompt, setPrompt] = useState('')\n const [model, setModel] = useState('')\n const [voice, setVoice] = useState('')\n const [speed, setSpeed] = useState('')\n const [duration, setDuration] = useState('')\n const [format, setFormat] = useState('mp3')\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [outputs, setOutputs] = useState<GeneratedAudio[]>([])\n const { entries, reload, clear } = useHistory()\n\n const visibleModels = useMemo(() => modelOptions.models\n .filter(entry => entry.category === undefined || entry.category === 'tts' && mode === 'tts' || entry.category === mode)\n .map(entry => entry.alias), [modelOptions.models, mode])\n\n useEffect(() => {\n if (visibleModels.length > 0 && !visibleModels.includes(model)) {\n setModel(visibleModels[0]!)\n }\n }, [visibleModels, model])\n\n const submit = async (): Promise<void> => {\n if (prompt.trim() === '') {\n setError(tt('prompt.required'))\n return\n }\n setLoading(true)\n setError(null)\n try {\n const response = await api.generate({\n mode,\n model: (model || visibleModels[0]) ?? '',\n prompt: prompt.trim(),\n ...(voice.trim() !== '' ? { voice: voice.trim() } : {}),\n ...(speed.trim() !== '' ? { speed: Number(speed) } : {}),\n ...(duration.trim() !== '' ? { duration: Number(duration) } : {}),\n ...(format.trim() !== '' ? { format: format.trim() } : {}),\n })\n if (!response.ok) {\n setError(response.message ?? '生成失败')\n return\n }\n setOutputs(response.outputs ?? [])\n reload()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setLoading(false)\n }\n }\n\n const modeLabel = useMemo(() => {\n if (mode === 'tts') return tt('mode.tts')\n if (mode === 'music') return tt('mode.music')\n return tt('mode.sfx')\n }, [mode])\n\n return (\n <div className={css.panel}>\n <header className={css.header}>\n <h2 className={css.title}>{tt('panel.title')}</h2>\n <span className={css.hint}>{modeLabel}</span>\n </header>\n <div className={css.layout}>\n <div className={css.form}>\n <div className={css.modeRow}>\n {(['tts', 'music', 'sfx'] as const).map(item => (\n <button\n key={item}\n type=\"button\"\n className={css.modeButton}\n data-active={mode === item ? 'true' : 'false'}\n onClick={() => setMode(item)}\n >\n {item === 'tts' ? tt('mode.tts') : item === 'music' ? tt('mode.music') : tt('mode.sfx')}\n </button>\n ))}\n </div>\n <label className={css.label}>\n <span>{mode === 'tts' ? '文本' : '提示词'}</span>\n <textarea className={css.textarea} value={prompt} onChange={event => setPrompt(event.target.value)} placeholder={tt('prompt.placeholder')} />\n </label>\n <label className={css.label}>\n <span>{tt('model.label')}</span>\n <select className={css.select} value={model} onChange={event => setModel(event.target.value)}>\n {visibleModels.length === 0 ? <option value=\"\">(当前模式暂无可用模型)</option> : null}\n {visibleModels.map(item => <option key={item} value={item}>{item}</option>)}\n </select>\n </label>\n {mode === 'tts' ? (\n <label className={css.label}>\n <span>{tt('voice.label')}</span>\n <input className={css.input} value={voice} onChange={event => setVoice(event.target.value)} placeholder=\"alloy / 自定义音色\" />\n </label>\n ) : null}\n <label className={css.label}>\n <span>{tt('speed.label')}</span>\n <input className={css.input} type=\"number\" step=\"0.1\" min=\"0.5\" max=\"2\" value={speed} onChange={event => setSpeed(event.target.value)} placeholder=\"1.0\" />\n </label>\n <label className={css.label}>\n <span>{tt('duration.label')}</span>\n <input className={css.input} type=\"number\" step=\"1\" min=\"1\" max=\"120\" value={duration} onChange={event => setDuration(event.target.value)} placeholder=\"30\" />\n </label>\n <label className={css.label}>\n <span>{tt('format.label')}</span>\n <select className={css.select} value={format} onChange={event => setFormat(event.target.value)}>\n <option value=\"mp3\">mp3</option>\n <option value=\"wav\">wav</option>\n <option value=\"flac\">flac</option>\n <option value=\"ogg\">ogg</option>\n <option value=\"pcm\">pcm</option>\n </select>\n </label>\n {!connected && <p className={css.hint}>{tt('config.missing')}</p>}\n <button type=\"button\" className={css.generate} disabled={loading || !connected || visibleModels.length === 0} onClick={() => void submit()}>\n {loading ? tt('generating') : tt('generate')}\n </button>\n </div>\n <div className={css.result}>\n {error !== null ? <p className={css.error}>{error}</p> : null}\n {outputs.length === 0 ? <p className={css.empty}>{tt('result.empty')}</p> : (\n <>\n <p className={css.hint}>{tt('result.done', { count: outputs.length })}</p>\n <div className={css.audioList}>\n {outputs.map((audio, index) => (\n <div className={css.audioCard} key={audio.id}>\n <audio className={css.audio} controls preload=\"metadata\" src={dataUrlOf(audio)} />\n <a className={css.download} href={dataUrlOf(audio)} download={`generated-${index + 1}.${audio.mime.split('/')[1]?.replace('mpeg', 'mp3') ?? 'mp3'}`}>下载</a>\n </div>\n ))}\n </div>\n </>\n )}\n </div>\n <aside className={css.history}>\n <div className={css.historyHeader}>\n <strong className={css.historyTitle}>{tt('history.title')}</strong>\n <button type=\"button\" onClick={clear} style={{ border: 0, background: 'none', cursor: 'pointer', color: 'inherit', fontSize: 12 }}>清空</button>\n </div>\n {entries.length === 0 ? <p className={css.historyEmpty}>{tt('history.empty')}</p> : (\n <div>\n {entries.map(entry => (\n <div className={css.historyItem} key={entry.id}>\n <div className={css.historyPrompt}>{entry.prompt}</div>\n <div className={css.historyMeta}>{entry.mode} · {entry.model}{entry.channel ? ` · ${entry.channel}` : ''}</div>\n {entry.audio.map((audio, index) => (\n <audio key={index} className={css.historyAudio} controls preload=\"none\" src={audio.url} />\n ))}\n </div>\n ))}\n </div>\n )}\n </aside>\n </div>\n </div>\n )\n}\n","/**\n * Panel view mounting for the AI 音频 panel.\n *\n * Like dsh-imagegen, the panel takes over the center column at the DOM level:\n * a container is appended inside the conversation grid item and a data\n * attribute on <html> hides/shows it.\n */\n\nimport { createRoot, type Root } from 'react-dom/client'\nimport type { AudiogenApi } from './api.ts'\nimport type { AudioGenController } from './controller.ts'\nimport { AudioGenPanel } from './AudioGenPanel.tsx'\nimport type { AudiogenScope } from './settings-scope.ts'\nimport css from './panel.module.css'\n\nexport const PANEL_VIEW_SELECTOR = '[data-dsh-audiogen-view]'\n\nconst CONVERSATION_COLUMN_SELECTOR = '[data-pane=\"conversation\"], [class*=\"centerCol\"]'\nconst ACTIVE_ATTR = 'data-dsh-audiogen-active'\nconst OTHER_ACTIVE_ATTRS = ['data-dsh-taskboard-active', 'data-dsh-ssh-active', 'data-dsh-imagegen-active']\nconst ACTIVATE_EVENT = 'dsh-panel-activate'\nconst PANEL_NAME = 'audiogen'\n\nfunction conversationColumn(): HTMLElement | undefined {\n return document.querySelector<HTMLElement>(CONVERSATION_COLUMN_SELECTOR) ?? undefined\n}\n\nexport function mountPanel(\n controller: AudioGenController,\n api: AudiogenApi,\n scope: AudiogenScope,\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 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.dshAudiogenView = ''\n container.className = css.view\n column.appendChild(container)\n root = createRoot(container)\n root.render(<AudioGenPanel api={api} scope={scope} />)\n }\n\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 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' || detail === 'imagegen') && controller.getSnapshot().panelOpen) {\n controller.close()\n }\n }\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 the entry row is injected at the DOM level after the shell's New Session\n * button. A MutationObserver self-heals when React re-renders.\n */\n\nimport type { AudioGenController } from './controller.ts'\nimport css from './panel.module.css'\n\nexport const ENTRY_SELECTOR = '[data-dsh-audiogen-entry]'\n\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\"><path d=\"M3 3.5h10v9H3z\"/><path d=\"M1.5 5.5v5\"/><path d=\"M14.5 5.5v5\"/><path d=\"M6 6.5l4 1.5-4 1.5z\"/></svg>'\n\nconst FAMILY_ENTRY_SELECTOR = '[data-dsh-taskboard-entry], [data-dsh-ssh-entry], [data-dsh-imagegen-entry], [data-dsh-audiogen-entry]'\n\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\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\nfunction createEntry(controller: AudioGenController, label: string, tooltip: string): HTMLButtonElement {\n const entry = document.createElement('button')\n entry.type = 'button'\n entry.dataset.dshAudiogenEntry = ''\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\nfunction placeEntry(root: HTMLElement, entry: HTMLButtonElement): boolean {\n const button = newSessionButton(root)\n if (button === undefined) return false\n if (entry.parentElement !== root) {\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\nexport function mountSidebarEntry(controller: AudioGenController, 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 const waitObserver = new MutationObserver(() => { tryPlace() })\n waitObserver.observe(document.body, { childList: true, subtree: true })\n\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 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 { AudiogenScope, 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 => ({\n alias: model.alias.trim(),\n id: model.id.trim() === '' ? model.alias.trim() : model.id.trim(),\n ...(model.category === undefined ? {} : { category: model.category }),\n }))\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: AudiogenScope) {\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: AudiogenScope): unknown {\n const view = scope.getSnapshot().value as { channels?: unknown } | undefined\n return Array.isArray(view?.channels) ? view.channels : []\n}\n","/**\n * The dsh-audiogen settings card.\n *\n * Registers into the official `settings.plugin.item` slot. It manages a list\n * of audio channels (each with API URL, per-channel secret, and model/voice\n * catalog), plus master switches.\n */\n\nimport { useEffect, 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, 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 { AudiogenScope } from './settings-scope.ts'\nimport { MODEL_API, PRESETS_API, type DiscoveredAudioModel, type ModelMapping, type PresetProviderView } from '../protocol.ts'\nimport type { AudioGenKey } from './locales.ts'\nimport css from './settings-card.module.css'\n\nexport interface AudioGenSettings {\n enabled?: boolean\n announceToAgent?: boolean\n allowAgentAudioGeneration?: boolean\n defaultModel?: string\n}\n\nexport interface AudioGenSettingsCardState extends CardShell {\n channels: ChannelsFormState\n enabled: CardFieldState\n announceToAgent: CardFieldState\n allowAgentAudioGeneration: CardFieldState\n defaultModel: CardFieldState\n}\n\nexport interface AudioGenSettingsCardFace extends CardActions {\n channels: ChannelsFormActions\n hooks: {\n audioGenSettingsCard: SnapshotStore<AudioGenSettingsCardState>\n }\n}\n\nexport class AudioGenSettingsCardController {\n private readonly form: CardForm<AudioGenSettings>\n private readonly channelsForm: ChannelsForm\n\n constructor(private readonly scope: AudiogenScope) {\n this.form = new CardForm(scope, [\n booleanField('enabled'),\n booleanField('announceToAgent'),\n booleanField('allowAgentAudioGeneration'),\n textField('defaultModel'),\n ])\n this.channelsForm = new ChannelsForm(scope)\n }\n\n private projection(): AudioGenSettingsCardState {\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 allowAgentAudioGeneration: this.form.field('allowAgentAudioGeneration'),\n defaultModel: this.form.field('defaultModel'),\n }\n }\n\n inject(): AudioGenSettingsCardFace {\n const cardStore = this.form.bind(() => this.projection())\n this.channelsForm.subscribe(() => { cardStore.set(this.projection()) })\n return {\n hooks: {\n audioGenSettingsCard: cardStore,\n },\n channels: this.channelsForm.actions(),\n ...this.form.actions(),\n }\n }\n}\n\nexport type AudioGenSettingsCardProps =\n PropsRuntime<'settings.plugin.item'>\n & PropsLocale<'dsh-audiogen'>\n & InjectFace<AudioGenSettingsCardFace>\n\nfunction newChannelDraft(preset: PresetProviderView | undefined, existing: ChannelDraft[]): ChannelDraft {\n const id = `ch-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`\n if (preset === undefined) {\n return { id, preset: '', name: '', apiUrl: '', models: [] }\n }\n return {\n id,\n preset: preset.id,\n name: preset.name,\n apiUrl: preset.apiUrl,\n models: preset.models.map(model => ({ ...model })),\n }\n}\n\nfunction modelsToText(models: ModelMapping[]): string {\n return models.map(model => `${model.alias}=${model.id}${model.category === undefined ? '' : ` @${model.category}`}`).join('\\n')\n}\n\nfunction textToModels(text: string): ModelMapping[] {\n return text.split(/\\n|,/).map(line => line.trim()).filter(Boolean).map(line => {\n const at = line.lastIndexOf(' @')\n const category = at >= 0 ? line.slice(at + 2).trim() : undefined\n const body = at >= 0 ? line.slice(0, at).trim() : line\n const eq = body.indexOf('=')\n const alias = eq >= 0 ? body.slice(0, eq).trim() : body.trim()\n const id = eq >= 0 ? body.slice(eq + 1).trim() : alias\n return {\n alias,\n id: id === '' ? alias : id,\n ...(category === undefined || category === '' ? {} : { category: category as NonNullable<ModelMapping['category']> }),\n }\n }).filter(model => model.alias !== '')\n}\n\nexport function AudioGenSettingsCard(props: AudioGenSettingsCardProps) {\n const { t } = props\n const state = props.useAudioGenSettingsCard(snapshot => snapshot)\n const [open, setOpen] = useState(false)\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 [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null)\n const [discovering, setDiscovering] = useState(false)\n const [discoverError, setDiscoverError] = useState<string | null>(null)\n\n const [editName, setEditName] = useState('')\n const [editUrl, setEditUrl] = useState('')\n const [editKey, setEditKey] = useState('')\n const [editModels, setEditModels] = useState('')\n const [editDefault, setEditDefault] = useState(false)\n\n const channels = state.channels.channels\n const editing = editingId === null ? undefined : channels.find(channel => channel.id === editingId)\n\n useEffect(() => {\n if (editing === undefined) return\n setEditName(editing.name)\n setEditUrl(editing.apiUrl)\n setEditKey('')\n setEditModels(modelsToText(editing.models))\n setEditDefault(editing.id === state.channels.defaultChannelId)\n }, [editingId, editing?.id]) // eslint-disable-line react-hooks/exhaustive-deps\n\n if (!state.available) return null\n\n const blocked = !state.dirty || state.invalid || state.saving || state.channels.saving\n\n const saveEdit = (): void => {\n if (editingId === null) return\n const existing = channels.find(channel => channel.id === editingId)\n const models = textToModels(editModels)\n const updated: ChannelDraft = {\n id: editingId,\n preset: existing?.preset ?? '',\n name: editName.trim(),\n apiUrl: editUrl.trim(),\n models,\n }\n const next = existing === undefined\n ? [...channels, updated]\n : channels.map(channel => channel.id === editingId ? updated : channel)\n props.channels.setChannels(next)\n if (editKey.trim() !== '') props.channels.setChannelKey(editingId, editKey.trim())\n if (editDefault) props.channels.setDefaultChannel(editingId)\n setEditingId(null)\n }\n\n const discoverModels = async (): Promise<void> => {\n if (editingId === null) return\n setDiscovering(true)\n setDiscoverError(null)\n try {\n const existing = channels.find(channel => channel.id === editingId)\n const response = await fetch(MODEL_API.discover, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n channelId: editingId,\n ...(editUrl.trim() !== '' ? { apiUrl: editUrl.trim() } : {}),\n ...(editKey.trim() !== '' ? { apiKey: editKey.trim() } : {}),\n }),\n })\n const body = await response.json() as { ok?: boolean; models?: DiscoveredAudioModel[]; message?: string; source?: string }\n if (body.ok !== true || body.models === undefined) {\n throw new Error(body.message ?? `HTTP ${response.status}`)\n }\n setEditModels(modelsToText([\n ...body.models,\n ...textToModels(editModels).filter(existingModel => !body.models!.some(model => model.id === existingModel.id)),\n ]))\n void existing\n } catch (error) {\n setDiscoverError(error instanceof Error ? error.message : String(error))\n } finally {\n setDiscovering(false)\n }\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')}: ${t('settings.title')}`}\n onClick={() => { setOpen(!open) }}\n >\n <span className={css.headText}>\n <span className={css.name}>{t('settings.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 ? null : (\n <div className={css.body}>\n {!state.writable ? <p className={css.readOnly} role=\"status\">{t('settings.readOnly')}</p> : null}\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 ? <p className={css.channelEmpty}>{t('channels.empty')}</p> : (\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.confirm')}: {channel.name || t('channels.untitled')}</span>\n <button type=\"button\" className={css.channelDanger} disabled={!state.writable} onClick={() => {\n props.channels.setChannels(channels.filter(candidate => candidate.id !== channel.id))\n if (isDefault && channels.length > 1) {\n const next = channels.find(candidate => candidate.id !== channel.id)\n if (next !== undefined) props.channels.setDefaultChannel(next.id)\n }\n setConfirmDeleteId(null)\n if (editingId === channel.id) setEditingId(null)\n }}>{t('channels.confirm')}</button>\n <button type=\"button\" className={css.channelAction} 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={!state.writable} 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 <span className={css.channelHost}>{channel.apiUrl || '(no url)'}</span>\n <span className={css.channelBadge} data-warn={!keyHeld || channel.models.length === 0 ? '' : undefined}>\n {keyHeld ? t('channels.keySet') : t('channels.keyMissing')}\n {' · '}\n {channel.models.length > 0 ? t('channels.modelCount', { n: channel.models.length }) : t('channels.noModels')}\n </span>\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 {presetPickerOpen ? (\n <div className={css.channelControls}>\n <p className={css.sectionHint}>{t('presets.title')}</p>\n {presetError !== null ? <p className={css.failed}>{presetError}</p> : null}\n <div className={css.channelAddRow}>\n <button type=\"button\" className={css.channelAdd} onClick={() => {\n setPresets([])\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 }}>{t('channels.addProvider')}</button>\n <button type=\"button\" className={css.channelAdd} onClick={() => {\n const draft = newChannelDraft(undefined, channels)\n props.channels.setChannels([...channels, draft])\n setPresetPickerOpen(false)\n setEditingId(draft.id)\n }}>{t('channels.addCustom')}</button>\n <button type=\"button\" className={css.channelAction} onClick={() => setPresetPickerOpen(false)}>×</button>\n </div>\n {presets.map(preset => (\n <button key={preset.id} type=\"button\" className={css.channelAdd} onClick={() => {\n const draft = newChannelDraft(preset, channels)\n props.channels.setChannels([...channels, draft])\n setPresetPickerOpen(false)\n setEditingId(draft.id)\n }}>\n {preset.name} — {preset.hint}\n </button>\n ))}\n </div>\n ) : (\n <div className={css.channelAddRow}>\n <button type=\"button\" className={css.channelAdd} disabled={!state.writable} onClick={() => { setPresetError(null); setPresetPickerOpen(true) }}>{t('channels.addProvider')}</button>\n <button type=\"button\" className={css.channelAdd} disabled={!state.writable} onClick={() => {\n const draft = newChannelDraft(undefined, channels)\n props.channels.setChannels([...channels, draft])\n setEditingId(draft.id)\n }}>{t('channels.addCustom')}</button>\n </div>\n )}\n </section>\n\n {editing !== undefined ? (\n <div className={css.body}>\n <div className={css.field}>\n <label className={css.label} htmlFor={`audiogen-name-${editing.id}`}>{t('channel.name')}</label>\n <input id={`audiogen-name-${editing.id}`} className={css.input} value={editName} onChange={event => setEditName(event.target.value)} />\n </div>\n <div className={css.field}>\n <label className={css.label} htmlFor={`audiogen-url-${editing.id}`}>{t('channel.apiUrl')}</label>\n <input id={`audiogen-url-${editing.id}`} className={css.input} value={editUrl} onChange={event => setEditUrl(event.target.value)} placeholder=\"https://…\" />\n </div>\n <div className={css.field}>\n <label className={css.label} htmlFor={`audiogen-key-${editing.id}`}>{t('channel.apiKey')}</label>\n <input id={`audiogen-key-${editing.id}`} className={css.input} type=\"password\" value={editKey} onChange={event => setEditKey(event.target.value)} placeholder={state.channels.keySet[editing.id] ? '••••••' : ''} />\n <p className={css.sectionHint}>{t('channel.apiKeyHint')}</p>\n </div>\n <div className={css.field}>\n <label className={css.label} htmlFor={`audiogen-models-${editing.id}`}>{t('channel.models')}</label>\n <textarea id={`audiogen-models-${editing.id}`} className={css.textarea} value={editModels} onChange={event => setEditModels(event.target.value)} />\n <p className={css.sectionHint}>{t('channel.modelsHint')}</p>\n <div className={css.channelAddRow}>\n <button type=\"button\" className={css.channelAdd} disabled={discovering || !state.writable} onClick={() => void discoverModels()}>\n {discovering ? '获取中…' : '获取可用模型'}\n </button>\n </div>\n {discoverError !== null ? <p className={css.failed}>{discoverError}</p> : null}\n </div>\n <label className={css.label}>\n <input type=\"checkbox\" checked={editDefault} onChange={event => setEditDefault(event.target.checked)} /> {t('channel.default')}\n </label>\n <div className={css.footer}>\n <button type=\"button\" className={css.discard} onClick={() => setEditingId(null)}>{t('channel.cancel')}</button>\n <button type=\"button\" className={css.save} onClick={saveEdit}>{t('channel.save')}</button>\n </div>\n </div>\n ) : null}\n\n <div className={css.field}>\n <label className={css.label}>\n <input type=\"checkbox\" checked={state.enabled.text === 'true' || state.enabled.text === ''} disabled={!state.writable} onChange={event => props.edit('enabled', String(event.target.checked))} /> {t('settings.enabled')}\n </label>\n </div>\n <div className={css.field}>\n <label className={css.label}>\n <input type=\"checkbox\" checked={state.announceToAgent.text === 'true' || state.announceToAgent.text === ''} disabled={!state.writable} onChange={event => props.edit('announceToAgent', String(event.target.checked))} /> {t('settings.announceToAgent')}\n </label>\n </div>\n <div className={css.field}>\n <label className={css.label}>\n <input type=\"checkbox\" checked={state.allowAgentAudioGeneration.text === 'true' || state.allowAgentAudioGeneration.text === ''} disabled={!state.writable} onChange={event => props.edit('allowAgentAudioGeneration', String(event.target.checked))} /> {t('settings.allowAgentAudio')}\n </label>\n </div>\n <div className={css.footer}>\n {state.failed ? <p className={css.failed}>保存失败</p> : null}\n <button type=\"button\" className={css.discard} disabled={!state.dirty || state.saving} onClick={() => props.discard()}>{t('settings.discard')}</button>\n <button type=\"button\" className={css.save} disabled={blocked} onClick={() => { void props.save(); void props.channels.commit() }}>\n {state.saving ? t('settings.saving') : t('settings.save')}\n </button>\n </div>\n </div>\n )}\n </li>\n )\n}\n","/**\n * Inline renderer for audio-generation tool results.\n *\n * The model-facing tool result is a JSON text envelope with same-origin audio\n * URLs; this view turns it into a small audio-player card.\n */\n\nimport type { ClientContext, SessionId } from '@deepseek-ai/dsh-client-runtime/client'\nimport { useEffect, useMemo, useState } from 'react'\nimport css from './audio-toolview.module.css'\n\nexport interface AudioToolViewOwnerProps {\n callId: string\n toolName: string\n block: unknown\n cwd?: string\n home?: string\n openFile: (path: string) => void\n inspect?: () => void\n}\n\ninterface AudioFileRef {\n id?: string\n url: string\n mime: string\n bytes: number\n}\n\ninterface AudioToolViewProps extends AudioToolViewOwnerProps {\n sessionId: SessionId\n}\n\nfunction isSettled(block: unknown): block is { content?: Array<{ type: string; text?: string }>; isError?: boolean } {\n return typeof block === 'object' && block !== null && 'content' in block\n}\n\nfunction textOf(block: unknown): string {\n if (!isSettled(block)) return ''\n return (block.content ?? [])\n .filter(content => content.type === 'text' && typeof content.text === 'string')\n .map(content => content.text as string)\n .join('\\n')\n}\n\nfunction parseResult(block: unknown): { status: string; message: string; audio: AudioFileRef[]; error?: string } {\n const text = textOf(block)\n if (text === '') return { status: 'running', message: '正在生成音频…', audio: [] }\n try {\n const parsed = JSON.parse(text) as { status?: string; message?: string; audio?: AudioFileRef[]; error?: string }\n return {\n status: parsed.status ?? 'completed',\n message: parsed.message ?? '',\n audio: Array.isArray(parsed.audio) ? parsed.audio.filter((item): item is AudioFileRef => {\n return typeof item === 'object' && item !== null && typeof (item as AudioFileRef).url === 'string'\n }) : [],\n ...(typeof parsed.error === 'string' ? { error: parsed.error } : {}),\n }\n } catch {\n return { status: 'completed', message: text, audio: [] }\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 mimeExt(mime: string): string {\n if (mime.includes('wav')) return 'wav'\n if (mime.includes('flac')) return 'flac'\n if (mime.includes('ogg')) return 'ogg'\n if (mime.includes('mp4') || mime.includes('m4a')) return 'm4a'\n return 'mp3'\n}\n\nexport function registerAudioToolviews(ctx: ClientContext): void {\n const AudioToolView = (props: AudioToolViewProps): React.JSX.Element => {\n const result = useMemo(() => parseResult(props.block), [props.block])\n const [active, setActive] = useState<string | null>(null)\n useEffect(() => { setActive(null) }, [props.callId])\n const title = props.toolName === 'generate_audio' ? '生成音频' : props.toolName\n return (\n <section className={css.root} data-state={result.status} data-tool={props.toolName}>\n <header className={css.header}>\n <span className={css.icon} aria-hidden=\"true\">♫</span>\n <strong>{title}</strong>\n <span className={css.status}>{statusLabel(result.status)}</span>\n </header>\n {result.message !== '' && <p className={css.message}>{result.message}</p>}\n {result.error !== undefined && <p className={css.error}>{result.error}</p>}\n {result.audio.length > 0 && (\n <div className={css.audios}>\n {result.audio.map((audio, index) => (\n <div className={css.audioRow} key={audio.id ?? audio.url}>\n <audio\n className={css.audio}\n controls\n preload=\"metadata\"\n src={audio.url}\n onPlay={() => setActive(audio.url)}\n />\n <a className={css.download} href={audio.url} download={`generated-${index + 1}.${mimeExt(audio.mime)}`}>\n 下载\n </a>\n </div>\n ))}\n </div>\n )}\n {result.audio.length === 0 && result.status !== 'running' && <p className={css.empty}>未返回可播放的音频。</p>}\n </section>\n )\n }\n\n ctx.slots.inject('tool.call.toolview', function* () {\n yield ctx.slots.register({ name: 'tool.call.toolview', key: 'generate_audio' }, AudioToolView)\n })\n}\n","/**\n * Browser-half entry for dsh-audiogen.\n *\n * Registers locale dictionaries, the settings card (Settings → Plugins → AI\n * 音频), and mounts the sidebar entry + generation panel. DOM mounting\n * failures are logged, never thrown.\n */\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport { AudiogenApi } from './api.ts'\nimport { AudioGenController } from './controller.ts'\nimport { tt } from './helpers.ts'\nimport { en, zh, type AudioGenKey } from './locales.ts'\nimport { mountPanel } from './mount.tsx'\nimport { mountSidebarEntry } from './sidebar-entry.ts'\nimport { AudioGenSettingsCard, AudioGenSettingsCardController } from './SettingsCard.tsx'\nimport { bindAudiogenScope, type AudiogenScope } from './settings-scope.ts'\nimport { registerAudioToolviews } from './audio-toolview.tsx'\n\nconst NS = 'dsh-audiogen'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n 'dsh-audiogen': AudioGenKey\n }\n\n interface SlotMap {\n 'settings.plugin.item': { kind: 'keyed'; scope: 'root'; owner: AudioGenPluginItemOwnerProps }\n 'tool.call.toolview': { kind: 'keyed'; scope: 'session'; owner: AudioToolViewOwnerProps }\n }\n}\n\nexport interface AudioGenPluginItemOwnerProps {\n children?: never\n}\n\nexport type AudioToolViewOwnerProps = {\n callId: string\n toolName: string\n block: unknown\n cwd?: string\n home?: string\n openFile: (path: string) => void\n inspect?: () => void\n}\n\nexport const inject = ['slots', 'locale', 'connection', 'sessions']\n\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-audiogen: dictionaries')\n registerAudioToolviews(ctx)\n\n const connection = ctx.get('connection') as ConnectionHandle | undefined\n const loopback = connection?.isLoopback === true\n const scope: AudiogenScope = bindAudiogenScope(loopback\n ? (input, init) => fetch(input, init)\n : () => { throw new Error('settings bridge is loopback-only') })\n\n ctx.effect(() => {\n const disposers = [\n ctx.on('connection/reset', () => { void scope.load() }),\n ]\n return () => { for (const dispose of disposers) dispose() }\n }, 'dsh-audiogen: settings scope invalidation')\n\n const settingsCard = new AudioGenSettingsCardController(scope)\n ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({\n name: 'settings.plugin.item',\n key: 'dsh-audiogen',\n locale: NS,\n inject: () => settingsCard.inject(),\n }, AudioGenSettingsCard))\n\n let uiDisposer: (() => void) | undefined\n const mountUi = (): void => {\n if (uiDisposer !== undefined) return\n const controller = new AudioGenController()\n const api = new AudiogenApi()\n const disposers: Array<() => void> = []\n try {\n disposers.push(mountSidebarEntry(controller, tt('entry.label'), tt('entry.tooltip')))\n disposers.push(mountPanel(controller, api, scope))\n } catch (error) {\n console.warn('[dsh-audiogen] mount failed:', error)\n }\n uiDisposer = () => {\n for (const dispose of disposers.splice(0)) dispose()\n uiDisposer = undefined\n }\n }\n const syncEnabled = (): void => {\n const snapshot = scope.getSnapshot()\n const enabled = snapshot.status === 'ready'\n ? snapshot.value?.enabled ?? true\n : snapshot.status === 'unavailable'\n if (enabled) mountUi()\n else uiDisposer?.()\n }\n scope.subscribe(syncEnabled)\n syncEnabled()\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["css","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/settings-scope.ts","../src/client/AudioGenPanel.tsx","../src/client/mount.tsx","../src/client/sidebar-entry.ts","../src/client/settings-form.ts","../src/client/channels-form.ts","../src/client/SettingsCard.tsx","../src/client/audio-toolview.tsx","../src/client/index.ts"],"sourcesContent":["/**\n * Wire contract shared by the host and client halves of dsh-audiogen:\n * settings namespace, route paths, generate payload/result shapes.\n * Pure types and constants — safe for the client bundle to inline.\n */\n\n/** Settings namespace this plugin owns (host settings seam + bridge). */\nexport const AUDIOGEN_SETTINGS_NAMESPACE = 'dsh-audiogen'\n\n/** Published package version shared by the host updater and the client UI. */\nexport const PLUGIN_VERSION = '0.3.2'\n\n/** Same-origin route family (loopback-only, mirroring dsh-imagegen). */\nexport const SETTINGS_API = {\n describe: '/api/dsh-audiogen/settings/describe',\n mutate: '/api/dsh-audiogen/settings/mutate',\n} as const\n\n/** The audio-generation proxy route. */\nexport const GENERATE_API = '/api/dsh-audiogen/generate' as const\n\n/** Host-mediated built-in provider catalog (channels the user can instantiate). */\nexport const PRESETS_API = '/api/dsh-audiogen/presets' as const\n\n/** Host-mediated model/voice discovery endpoint. */\nexport const MODEL_API = {\n discover: '/api/dsh-audiogen/models/discover',\n} as const\n\n/** Loopback-only audio file reader for panel/tool-result previews. */\nexport const AUDIO_API = {\n file: '/api/dsh-audiogen/audio',\n} as const\n\n/** Host-persisted generation history routes. */\nexport const HISTORY_API = {\n list: '/api/dsh-audiogen/history/list',\n append: '/api/dsh-audiogen/history/append',\n remove: '/api/dsh-audiogen/history/remove',\n clear: '/api/dsh-audiogen/history/clear',\n audio: '/api/dsh-audiogen/history/audio',\n} as const\n\n/** Maximum number of history entries retained host-side (oldest evicted). */\nexport const HISTORY_MAX = 50\n\n/** Audio generation modes. */\nexport type AudioMode = 'tts' | 'music' | 'sfx' | 'voice_design'\n\n/** The capability category of an audio model/voice. */\nexport type AudioModelCategory =\n | 'tts'\n | 'music'\n | 'sfx'\n | 'voice_design'\n | 'voice_clone'\n\n/** One model mapping in a channel's catalog: display alias → upstream id. */\nexport interface ModelMapping {\n /** User-facing model/voice name (defaults to the upstream id). */\n alias: string\n /** Upstream model or voice id sent to the provider. */\n id: string\n /** Optional capability category, used by the UI to group model lists. */\n category?: AudioModelCategory\n}\n\n/** A model/voice discovered from a vendor endpoint (not yet persisted). */\nexport interface DiscoveredAudioModel extends ModelMapping {\n /** Optional human-readable description from the vendor. */\n description?: string\n}\n\n/**\n * One configured audio channel (provider). Secrets never live here — the API\n * key is stored at `channelSecrets.<channelId>`.\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, panel, and Agent guidance. */\n name: string\n /** Provider base URL. */\n apiUrl: string\n /** The channel's model/voice 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 /** Official vendor website, shown as a link in the channel editor. */\n site?: string\n models: ModelMapping[]\n}\n\n/** A client → host generate request. */\nexport interface GenerateAudioRequest {\n mode: AudioMode\n /** User-facing model/voice alias; host maps to upstream id. */\n model: string\n /** TTS text or music/sfx prompt. */\n prompt: string\n /** Optional voice alias for TTS. */\n voice?: string\n /** Optional preview text for voice-design APIs. */\n previewText?: string\n /** Optional speaking rate / speed multiplier. */\n speed?: number\n /** Requested duration in seconds (music/sfx). */\n duration?: number\n /** Output format, e.g. mp3, wav, pcm. */\n format?: string\n /** Channel this request targets (host falls back to default). */\n channelId?: string\n /** Channel display name snapshot (host-filled). */\n channel?: string\n /** Upstream model id actually sent (host-filled from alias mapping). */\n upstream?: string\n\n // ---- MiniMax TTS 专属字段(其他厂商渠道忽略)——————\n /** MiniMax 音色情绪,如 happy/sad/angry/nervous/fearful/bored;默认按音色自身。 */\n emotion?: string\n /** MiniMax 音量,范围 0-10,默认 1。 */\n vol?: number\n /** MiniMax 音调偏移(半音),范围 -12~12,默认 0。 */\n pitch?: number\n /** MiniMax 文本归一化处理开关(默认 true)。 */\n textNormalization?: boolean\n /** MiniMax 数学公式朗读开关(默认 false)。 */\n latexRead?: boolean\n /** MiniMax 发音词典 tone 条目,元素形如 \"处理/(chu3)(li3)\" 或 \"危险/dangerous\"。 */\n pronunciationTone?: string[]\n /** MiniMax 采样率:16000/24000/32000/44100/48000,默认 32000。 */\n sampleRate?: number\n /** MiniMax 码率(bps):64000-320000,默认 128000。 */\n bitrate?: number\n /** MiniMax 声道数:1 或 2,默认 1。 */\n audioChannel?: number\n /** MiniMax 强制 CBR 编码(avoid VBR),默认 false。 */\n forceCbr?: boolean\n /** MiniMax 字幕开关:true 时响应携带字幕内容/文件。 */\n subtitleEnable?: boolean\n /** MiniMax AIGC 水印开关。 */\n aigcWatermark?: boolean\n /** MiniMax 语言增强(language_boost),如\"中英混读\",按模型支持情况。 */\n languageBoost?: string\n /** MiniMax 变声参数(voice_modify,speech-2.8 等支持)。 */\n voiceModify?: { pitch?: number; intensity?: number; timbre?: number; soundEffects?: string }\n /** MiniMax 双音色混合权重(timbre_weights)。 */\n timbreWeights?: Array<{ voiceId: string; weight: number }>\n}\n\n/** One generated audio, normalized host-side to base64. */\nexport interface GeneratedAudio {\n /** Raw base64 payload (no data: prefix). */\n b64: string\n /** MIME type, e.g. audio/mpeg. */\n mime: string\n /** Exact encoded byte length. */\n bytes: number\n /** Optional duration in seconds when the API reports one. */\n duration?: number\n /** Same-origin URL served by the host ('' when unavailable). */\n url: string\n /** Stable audio id / file name. */\n id: string\n /** Optional voice id returned by a voice-design API. */\n voiceId?: string\n}\n\n/** Successful generate outcome. */\nexport interface GenerateAudioResult {\n outputs: GeneratedAudio[]\n /** Updated host-persisted history, when returned. */\n history?: HistoryEntry[]\n /** Persistence failure after audio was generated. */\n historyError?: string\n}\n\n/** One audio reference as the browser consumes it. */\nexport interface HistoryAudioRef {\n /** Same-origin URL. */\n url: string\n /** MIME type, e.g. audio/mpeg. */\n mime: string\n /** Duration in seconds when known. */\n duration?: number\n /** Optional generated voice id. */\n voiceId?: string\n}\n\n/** A saved generation as the browser consumes it. */\nexport interface HistoryEntry {\n id: string\n createdAt: number\n mode: AudioMode\n model: string\n prompt: string\n voice?: string\n voiceId?: string\n speed?: number\n duration?: number\n format?: string\n audio: HistoryAudioRef[]\n channelId?: string\n channel?: string\n}\n\n/** A history entry the client submits for persistence (audio still carries base64). */\nexport interface HistoryEntryInput {\n id: string\n createdAt: number\n mode: AudioMode\n model: string\n prompt: string\n voice?: string\n voiceId?: string\n speed?: number\n duration?: number\n format?: string\n audio: GeneratedAudio[]\n channelId?: string\n channel?: string\n}\n\n/** The plugin settings fields edited by the settings card and panel. */\nexport interface AudiogenConfig {\n enabled?: boolean\n announceToAgent?: boolean\n allowAgentAudioGeneration?: boolean\n channels?: ChannelConfig[]\n channelSecrets?: Record<string, string>\n defaultChannelId?: string\n /** Optional default voice/model alias for quick generation. */\n defaultModel?: string\n}\n","/**\n * Browser-side API client for the audio generation and history routes.\n */\n\nimport { GENERATE_API, HISTORY_API, type GenerateAudioRequest, type GeneratedAudio, type HistoryEntry } from '../protocol.ts'\n\nexport interface GenerateResponse {\n ok: boolean\n outputs?: GeneratedAudio[]\n history?: HistoryEntry[]\n historyError?: string\n code?: string\n message?: string\n}\n\nexport class AudiogenApi {\n async generate(request: GenerateAudioRequest): Promise<GenerateResponse> {\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 response.json() as GenerateResponse\n return body\n }\n\n async history(): Promise<HistoryEntry[]> {\n const response = await fetch(HISTORY_API.list, { method: 'POST' })\n const body = await response.json() as { ok?: boolean; history?: HistoryEntry[] }\n return body.ok === true ? (body.history ?? []) : []\n }\n\n async clearHistory(): Promise<void> {\n await fetch(HISTORY_API.clear, { method: 'POST' })\n }\n}\n","/**\n * Audio panel controller: the single owner of the panel's open/closed state.\n * Framework-free so the DOM mounts and the React panel share one tiny\n * subscription surface.\n */\n\nexport interface AudioGenControllerSnapshot {\n panelOpen: boolean\n}\n\nexport class AudioGenController {\n private panelOpen = false\n private listeners = new Set<() => void>()\n\n getSnapshot(): AudioGenControllerSnapshot {\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-audiogen surface copy: zh is the key source, en mirrors every key.\n */\n\nexport const zh = {\n 'entry.label': 'AI 音频',\n 'entry.tooltip': 'AI 音频面板(TTS / 音乐 / 音效)',\n 'panel.title': 'AI 音频',\n 'mode.tts': '文本转语音',\n 'mode.music': '音乐生成',\n 'mode.sfx': '音效生成',\n 'mode.voiceDesign': '音色设计',\n 'prompt.placeholder': '输入文本、音乐/音效描述,或音色设计描述…',\n 'prompt.required': '请输入文本或提示词',\n 'model.label': '模型 / 音色',\n 'voice.label': '音色',\n 'speed.label': '语速',\n 'duration.label': '时长(秒)',\n 'format.label': '输出格式',\n 'generate': '开始生成',\n 'generating': '生成中…',\n 'download': '下载',\n 'result.empty': '生成结果将显示在这里',\n 'result.done': '生成完成,共 {count} 段音频',\n 'history.title': '历史记录',\n 'history.empty': '暂无历史记录',\n 'config.missing': '尚未配置音频 API:请前往「设置 → 插件 → AI 音频」添加渠道。',\n 'config.disabled': '插件已停用,请在设置中重新启用。',\n 'settings.title': 'AI 音频(dsh-audiogen)',\n 'settings.description': '配置多厂商音频生成 API 地址与密钥',\n 'settings.collapse': '收起',\n 'settings.expand': '展开',\n 'settings.enabled': '启用插件',\n 'settings.announceToAgent': '向 Agent 播报本插件',\n 'settings.allowAgentAudio': '允许 Agent 调用音频生成',\n 'settings.save': '保存',\n 'settings.saving': '保存中…',\n 'settings.discard': '放弃修改',\n 'settings.unsaved': '有未保存的修改',\n 'settings.readOnly': '当前设置为只读。',\n 'channels.title': '音频渠道',\n 'channels.hint': '每个渠道是一个独立的音频厂商/API 端点,可配置多个。',\n 'channels.empty': '还没有渠道。',\n 'channels.addProvider': '+ 添加提供方',\n 'channels.addProviderLoading': '加载提供方…',\n 'channels.addProviderFailed': '提供方目录加载失败,请点击重试。',\n 'channels.addCustom': '+ 添加自定义提供方',\n 'channels.edit': '编辑',\n 'channels.delete': '删除',\n 'channels.confirm': '确认删除',\n 'channels.cancel': '取消',\n 'channels.keySet': '已填密钥',\n 'channels.keyMissing': '未填密钥',\n 'channels.modelCount': '{n} 个模型/音色',\n 'channels.noModels': '未配置模型',\n 'channels.statusReady': '可用',\n 'channels.statusIncomplete': '未完成',\n 'channels.untitled': '未命名渠道',\n 'channel.title': '渠道设置',\n 'channel.editTitle': '编辑渠道',\n 'channel.provider': '提供方',\n 'channel.providerCustom': '自定义渠道',\n 'channel.providerCustomHint': '任意 OpenAI 兼容 TTS 或通用音频 POST 接口',\n 'channel.site': '官网',\n 'channel.name': '名称',\n 'channel.namePlaceholder': '渠道名称(如:MiniMax 主渠道)',\n 'channel.apiUrl': 'API 地址',\n 'channel.apiUrlPlaceholder': '提供方默认地址',\n 'channel.apiUrlHint': '留空使用提供方默认地址。',\n 'channel.apiKey': 'API 密钥',\n 'channel.apiKeyHint': '输入 API 密钥后即可使用该渠道。',\n 'channel.apiKeyStoredHint': '已保存密钥;留空保持不变,输入新值可更换。',\n 'channel.clearKey': '清除密钥',\n 'channel.customSettings': '自定义设置',\n 'channel.modelsTitle': '模型 / 音色目录',\n 'channel.modelsCount': '{n} 个模型/音色',\n 'channel.modelsNone': '未添加',\n 'channel.modelsEmpty': '尚未添加模型/音色:面板与 Agent 将无可选模型;保存后仍可直接输入目录外的 ID 进行生成。',\n 'channel.modelAlias': '显示名称',\n 'channel.modelId': '上游 ID',\n 'channel.modelCategory': '分类',\n 'channel.category.auto': '自动',\n 'channel.category.tts': '语音',\n 'channel.category.music': '音乐',\n 'channel.category.sfx': '音效',\n 'channel.category.voice_design': '音色设计',\n 'channel.category.voice_clone': '音色克隆',\n 'channel.addModel': '添加模型',\n 'channel.removeModel': '移除',\n 'channel.fetchModels': '获取可用模型',\n 'channel.fetchingModels': '获取中…',\n 'channel.discoverNeedsUrlKey': '填写 API 地址与密钥后可获取模型',\n 'channel.fetchEmpty': '未发现音频相关模型。',\n 'channel.discoverSource': '来源:{source}',\n 'channel.candidates': '发现 {n} 个可用模型/音色',\n 'channel.selectAll': '全选',\n 'channel.clearSelection': '清空',\n 'channel.adoptSelected': '添加所选({n})',\n 'channel.default': '设为默认渠道',\n 'channel.cancel': '取消',\n 'channel.save': '保存渠道',\n} as const\n\nexport type AudioGenKey = keyof typeof zh\n\nexport const en: Record<AudioGenKey, string> = {\n 'entry.label': 'AI Audio',\n 'entry.tooltip': 'AI audio panel (TTS / music / SFX)',\n 'panel.title': 'AI Audio',\n 'mode.tts': 'Text to speech',\n 'mode.music': 'Music',\n 'mode.sfx': 'Sound effects',\n 'mode.voiceDesign': 'Voice design',\n 'prompt.placeholder': 'Text to speak, or a music/SFX/voice-design description…',\n 'prompt.required': 'Prompt or text is required',\n 'model.label': 'Model / voice',\n 'voice.label': 'Voice',\n 'speed.label': 'Speed',\n 'duration.label': 'Duration (s)',\n 'format.label': 'Format',\n 'generate': 'Generate',\n 'generating': 'Generating…',\n 'download': 'Download',\n 'result.empty': 'Generated audio will appear here.',\n 'result.done': 'Done, {count} audio file(s).',\n 'history.title': 'History',\n 'history.empty': 'No audio history yet.',\n 'config.missing': 'No audio API configured. Open Settings > Plugins > AI Audio and add a channel.',\n 'config.disabled': 'The plugin is disabled. Enable it in Settings.',\n 'settings.title': 'AI Audio (dsh-audiogen)',\n 'settings.description': 'Configure multi-vendor audio generation endpoints and keys',\n 'settings.collapse': 'Collapse',\n 'settings.expand': 'Expand',\n 'settings.enabled': 'Enable plugin',\n 'settings.announceToAgent': 'Announce this plugin to agents',\n 'settings.allowAgentAudio': 'Allow agents to generate audio',\n 'settings.save': 'Save',\n 'settings.saving': 'Saving…',\n 'settings.discard': 'Discard',\n 'settings.unsaved': 'Unsaved changes',\n 'settings.readOnly': 'Settings are read-only.',\n 'channels.title': 'Audio channels',\n 'channels.hint': 'Each channel is an independent audio vendor/API endpoint.',\n 'channels.empty': 'No channels yet.',\n 'channels.addProvider': '+ Add provider',\n 'channels.addProviderLoading': 'Loading providers…',\n 'channels.addProviderFailed': 'Failed to load the provider catalog. Click to retry.',\n 'channels.addCustom': '+ Add custom provider',\n 'channels.edit': 'Edit',\n 'channels.delete': 'Delete',\n 'channels.confirm': 'Confirm delete',\n 'channels.cancel': 'Cancel',\n 'channels.keySet': 'Key set',\n 'channels.keyMissing': 'No key',\n 'channels.modelCount': '{n} model(s)/voice(s)',\n 'channels.noModels': 'No models configured',\n 'channels.statusReady': 'Ready',\n 'channels.statusIncomplete': 'Incomplete',\n 'channels.untitled': 'Untitled channel',\n 'channel.title': 'Channel settings',\n 'channel.editTitle': 'Edit channel',\n 'channel.provider': 'Provider',\n 'channel.providerCustom': 'Custom provider',\n 'channel.providerCustomHint': 'Any OpenAI-compatible TTS or generic audio POST endpoint',\n 'channel.site': 'Website',\n 'channel.name': 'Name',\n 'channel.namePlaceholder': 'Channel name (e.g. MiniMax main)',\n 'channel.apiUrl': 'API URL',\n 'channel.apiUrlPlaceholder': 'Provider default',\n 'channel.apiUrlHint': 'Leave blank to use the provider default.',\n 'channel.apiKey': 'API key',\n 'channel.apiKeyHint': 'Enter the API key to use this channel.',\n 'channel.apiKeyStoredHint': 'A key is stored; leave blank to keep it, or enter a new one.',\n 'channel.clearKey': 'Clear key',\n 'channel.customSettings': 'Custom settings',\n 'channel.modelsTitle': 'Model / voice catalog',\n 'channel.modelsCount': '{n} model(s)/voice(s)',\n 'channel.modelsNone': 'None',\n 'channel.modelsEmpty': 'No models yet: the panel and agents will have nothing to pick. You can still send an ID outside the catalog after saving.',\n 'channel.modelAlias': 'Display name',\n 'channel.modelId': 'Upstream ID',\n 'channel.modelCategory': 'Category',\n 'channel.category.auto': 'Auto',\n 'channel.category.tts': 'Speech',\n 'channel.category.music': 'Music',\n 'channel.category.sfx': 'SFX',\n 'channel.category.voice_design': 'Voice design',\n 'channel.category.voice_clone': 'Voice clone',\n 'channel.addModel': 'Add model',\n 'channel.removeModel': 'Remove',\n 'channel.fetchModels': 'Fetch available models',\n 'channel.fetchingModels': 'Fetching…',\n 'channel.discoverNeedsUrlKey': 'Fill in the API URL and key to fetch models',\n 'channel.fetchEmpty': 'No audio-related models found.',\n 'channel.discoverSource': 'Source: {source}',\n 'channel.candidates': '{n} available model(s)/voice(s) found',\n 'channel.selectAll': 'Select all',\n 'channel.clearSelection': 'Clear',\n 'channel.adoptSelected': 'Add selected ({n})',\n 'channel.default': 'Set as default channel',\n 'channel.cancel': 'Cancel',\n 'channel.save': 'Save channel',\n}\n","/**\n * Shared panel helpers: active-dictionary pick and a small error extractor.\n */\n\nimport { en, zh, type AudioGenKey } from './locales.ts'\n\nexport type TranslateValues = Record<string, string | number>\n\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\nexport function tt(key: AudioGenKey, 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\nexport function errorMessage(error: unknown): string {\n if (error instanceof Error) return error.message\n return String(error)\n}\n","/**\n * Browser-side settings scope for the dsh-audiogen namespace, served by the\n * plugin's own loopback bridge routes (/api/dsh-audiogen/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 AudioModelCategory, type ChannelConfig } from '../protocol.ts'\n\n/** The fields this plugin's settings card edits. */\nexport interface AudiogenConfig {\n enabled?: boolean\n announceToAgent?: boolean\n allowAgentAudioGeneration?: 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 defaultModel?: 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 AudiogenScope extends SettingsScope<AudiogenConfig> {\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-audiogen 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 bindAudiogenScope(fetchFn: typeof fetch = fetch): AudiogenScope {\n const controller = new BridgeScopeController<AudiogenConfig>(createBridgeApi(fetchFn).settings, {\n namespace: 'dsh-audiogen',\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 audioModelOptions(config: AudiogenConfig | undefined): {\n models: Array<{ alias: string; category?: AudioModelCategory }>\n defaultChannelId?: string\n} {\n const channels = config?.channels ?? []\n if (channels.length === 0) {\n return { models: [] }\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: Array<{ alias: string; category?: AudioModelCategory }> = []\n const seen = new Set<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 === '' || seen.has(model.alias)) continue\n seen.add(model.alias)\n models.push({ alias: model.alias, ...(model.category === undefined ? {} : { category: model.category }) })\n }\n }\n return models.length > 0 ? { models, defaultChannelId: defaultId } : { models: [], defaultChannelId: defaultId }\n}\n","\n/**\n * The AI 音频 panel: a compact audio-generation studio.\n * TTS / music / SFX / voice design are separated; each mode only lists\n * compatible models and shows its own parameters.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport type { AudiogenApi } from './api.ts'\nimport type { AudiogenScope } from './settings-scope.ts'\nimport { audioModelOptions } from './settings-scope.ts'\nimport { tt } from './helpers.ts'\nimport { HISTORY_API, type AudioMode, type GeneratedAudio, type HistoryEntry } from '../protocol.ts'\nimport css from './audio-panel.module.css'\n\nfunction useConfig(scope: AudiogenScope) {\n const [value, setValue] = useState(scope.getSnapshot().value)\n useEffect(() => scope.subscribe(() => { setValue(scope.getSnapshot().value) }), [scope])\n return value\n}\n\nfunction useHistory(): { entries: HistoryEntry[]; reload: () => void; clear: () => void } {\n const [entries, setEntries] = useState<HistoryEntry[]>([])\n const reload = (): void => {\n void fetch(HISTORY_API.list, { method: 'POST' })\n .then(async response => {\n const body = await response.json() as { ok?: boolean; history?: HistoryEntry[] }\n if (body.ok === true) setEntries(body.history ?? [])\n })\n .catch(() => { /* history is best-effort */ })\n }\n useEffect(() => { reload() }, [])\n const clear = (): void => {\n void fetch(HISTORY_API.clear, { method: 'POST' })\n .then(() => reload())\n .catch(() => { /* best-effort */ })\n }\n return { entries, reload, clear }\n}\n\nfunction dataUrlOf(audio: GeneratedAudio): string {\n return `data:${audio.mime};base64,${audio.b64}`\n}\n\nexport function AudioGenPanel(props: { api: AudiogenApi; scope: AudiogenScope }) {\n const { api, scope } = props\n const config = useConfig(scope)\n const enabled = config?.enabled ?? true\n const modelOptions = audioModelOptions(config)\n const channels = config?.channels ?? []\n const connected = enabled && channels.some(channel => {\n const keyHeld = scope.getSecretSetSnapshot(`channelSecrets.${channel.id}`)\n return channel.apiUrl.trim() !== '' && keyHeld && (channel.models.length > 0 || channel.preset === 'minimax')\n })\n\n const [mode, setMode] = useState<AudioMode>('tts')\n const [prompt, setPrompt] = useState('')\n const [previewText, setPreviewText] = useState('')\n const [model, setModel] = useState('')\n const [voice, setVoice] = useState('')\n const [speed, setSpeed] = useState('')\n const [duration, setDuration] = useState('')\n const [format, setFormat] = useState('mp3')\n // MiniMax TTS 高级参数(其他厂商忽略)\n const [emotion, setEmotion] = useState('')\n const [vol, setVol] = useState('')\n const [pitch, setPitch] = useState('')\n const [toneText, setToneText] = useState('')\n const [sampleRate, setSampleRate] = useState('')\n const [bitrate, setBitrate] = useState('')\n const [audioChannel, setAudioChannel] = useState('')\n const [subtitle, setSubtitle] = useState(false)\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [outputs, setOutputs] = useState<GeneratedAudio[]>([])\n const { entries, reload, clear } = useHistory()\n\n const isMiniMaxChannel = useMemo(() => {\n const target = channels.find(candidate => candidate.id === modelOptions.defaultChannelId) ?? channels[0]\n return target !== undefined && (target.preset === 'minimax' || /minimax/i.test(target.apiUrl))\n }, [channels, modelOptions.defaultChannelId])\n\n const visibleModels = useMemo(() => {\n if (mode === 'voice_design') return []\n return modelOptions.models\n .filter(entry => entry.category === undefined || entry.category === 'tts' && mode === 'tts' || entry.category === mode)\n .map(entry => entry.alias)\n }, [modelOptions.models, mode])\n\n useEffect(() => {\n if (visibleModels.length > 0 && !visibleModels.includes(model)) {\n setModel(visibleModels[0]!)\n }\n }, [visibleModels, model])\n\n const submit = async (): Promise<void> => {\n if (prompt.trim() === '') {\n setError(tt('prompt.required'))\n return\n }\n setLoading(true)\n setError(null)\n try {\n const response = await api.generate({\n mode,\n model: (model || visibleModels[0]) ?? '',\n prompt: prompt.trim(),\n ...(previewText.trim() !== '' ? { previewText: previewText.trim() } : {}),\n ...(voice.trim() !== '' ? { voice: voice.trim() } : {}),\n ...(speed.trim() !== '' ? { speed: Number(speed) } : {}),\n ...(duration.trim() !== '' ? { duration: Number(duration) } : {}),\n ...(format.trim() !== '' ? { format: format.trim() } : {}),\n ...(emotion.trim() !== '' ? { emotion: emotion.trim() } : {}),\n ...(vol.trim() !== '' ? { vol: Number(vol) } : {}),\n ...(pitch.trim() !== '' ? { pitch: Number(pitch) } : {}),\n ...(toneText.trim() !== '' ? { pronunciationTone: toneText.split('\\n').map(item => item.trim()).filter(item => item !== '') } : {}),\n ...(sampleRate.trim() !== '' ? { sampleRate: Number(sampleRate) } : {}),\n ...(bitrate.trim() !== '' ? { bitrate: Number(bitrate) } : {}),\n ...(audioChannel.trim() !== '' ? { audioChannel: Number(audioChannel) } : {}),\n ...(subtitle ? { subtitleEnable: true } : {}),\n })\n if (!response.ok) {\n setError(response.message ?? '生成失败')\n return\n }\n setOutputs(response.outputs ?? [])\n reload()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setLoading(false)\n }\n }\n\n const modeLabel = useMemo(() => {\n if (mode === 'tts') return tt('mode.tts')\n if (mode === 'music') return tt('mode.music')\n if (mode === 'sfx') return tt('mode.sfx')\n return tt('mode.voiceDesign')\n }, [mode])\n\n const needModel = mode !== 'voice_design'\n\n return (\n <div className={css.panel}>\n <header className={css.header}>\n <h2 className={css.title}>{tt('panel.title')}</h2>\n <span className={css.hint}>{modeLabel}</span>\n </header>\n <div className={css.layout}>\n <div className={css.form}>\n <div className={css.modeRow}>\n {(['tts', 'music', 'sfx', 'voice_design'] as const).map(item => (\n <button\n key={item}\n type=\"button\"\n className={css.modeButton}\n data-active={mode === item ? 'true' : 'false'}\n onClick={() => setMode(item)}\n >\n {item === 'tts' ? tt('mode.tts') : item === 'music' ? tt('mode.music') : item === 'sfx' ? tt('mode.sfx') : tt('mode.voiceDesign')}\n </button>\n ))}\n </div>\n\n <label className={css.label}>\n <span>{mode === 'voice_design' ? '音色描述' : mode === 'tts' ? '文本' : '提示词'}</span>\n <textarea className={css.textarea} value={prompt} onChange={event => setPrompt(event.target.value)} placeholder={tt('prompt.placeholder')} />\n </label>\n\n {mode === 'voice_design' ? (\n <label className={css.label}>\n <span>试听文本</span>\n <input className={css.input} value={previewText} onChange={event => setPreviewText(event.target.value)} placeholder=\"你好,这是新设计的音色试听。\" />\n </label>\n ) : null}\n\n {needModel ? (\n <label className={css.label}>\n <span>{tt('model.label')}</span>\n <select className={css.select} value={model} onChange={event => setModel(event.target.value)}>\n {visibleModels.length === 0 ? <option value=\"\">(当前模式暂无可用模型)</option> : null}\n {visibleModels.map(item => <option key={item} value={item}>{item}</option>)}\n </select>\n </label>\n ) : null}\n\n {mode === 'tts' ? (\n <label className={css.label}>\n <span>{tt('voice.label')}</span>\n <input className={css.input} value={voice} onChange={event => setVoice(event.target.value)} placeholder={isMiniMaxChannel ? 'male-qn-qingse / female-shaonv' : 'alloy / 自定义音色'} />\n </label>\n ) : null}\n\n {mode === 'tts' ? (\n <label className={css.label}>\n <span>{tt('speed.label')}</span>\n <input className={css.input} type=\"number\" step=\"0.1\" min=\"0.5\" max=\"2\" value={speed} onChange={event => setSpeed(event.target.value)} placeholder=\"1.0\" />\n </label>\n ) : null}\n\n {mode === 'tts' && isMiniMaxChannel ? (\n <details className={css.advanced}>\n <summary>MiniMax 高级参数</summary>\n <label className={css.label}>\n <span>情绪 emotion</span>\n <input className={css.input} value={emotion} onChange={event => setEmotion(event.target.value)} placeholder=\"happy / sad / angry / nervous…\" />\n </label>\n <div className={css.row}>\n <label className={css.label}>\n <span>音量 vol (0-10)</span>\n <input className={css.input} type=\"number\" min=\"0\" max=\"10\" step=\"0.5\" value={vol} onChange={event => setVol(event.target.value)} placeholder=\"1\" />\n </label>\n <label className={css.label}>\n <span>音调 pitch (-12~12)</span>\n <input className={css.input} type=\"number\" min=\"-12\" max=\"12\" value={pitch} onChange={event => setPitch(event.target.value)} placeholder=\"0\" />\n </label>\n </div>\n <div className={css.row}>\n <label className={css.label}>\n <span>采样率</span>\n <input className={css.input} type=\"number\" min=\"16000\" max=\"48000\" step=\"8000\" value={sampleRate} onChange={event => setSampleRate(event.target.value)} placeholder=\"32000\" />\n </label>\n <label className={css.label}>\n <span>码率 bps</span>\n <input className={css.input} type=\"number\" min=\"64000\" max=\"320000\" step=\"8000\" value={bitrate} onChange={event => setBitrate(event.target.value)} placeholder=\"128000\" />\n </label>\n <label className={css.label}>\n <span>声道</span>\n <select className={css.select} value={audioChannel} onChange={event => setAudioChannel(event.target.value)}>\n <option value=\"\">默认(1)</option>\n <option value=\"1\">1</option>\n <option value=\"2\">2</option>\n </select>\n </label>\n </div>\n <label className={css.label}>\n <span>发音词典(每行一条:\"文字/读音\")</span>\n <textarea className={css.textarea} value={toneText} onChange={event => setToneText(event.target.value)} placeholder={'处理/(chu3)(li3)\\n危险/dangerous'} />\n </label>\n <label className={css.checkbox}>\n <input type=\"checkbox\" checked={subtitle} onChange={event => setSubtitle(event.target.checked)} />\n <span>生成字幕 subtitle_enable</span>\n </label>\n </details>\n ) : null}\n\n {mode === 'music' || mode === 'sfx' ? (\n <label className={css.label}>\n <span>{tt('duration.label')}</span>\n <input className={css.input} type=\"number\" step=\"1\" min=\"1\" max=\"120\" value={duration} onChange={event => setDuration(event.target.value)} placeholder=\"30\" />\n </label>\n ) : null}\n\n {needModel ? (\n <label className={css.label}>\n <span>{tt('format.label')}</span>\n <select className={css.select} value={format} onChange={event => setFormat(event.target.value)}>\n <option value=\"mp3\">mp3</option>\n <option value=\"wav\">wav</option>\n <option value=\"flac\">flac</option>\n <option value=\"ogg\">ogg</option>\n <option value=\"pcm\">pcm</option>\n </select>\n </label>\n ) : null}\n\n {!connected && <p className={css.hint}>{tt('config.missing')}</p>}\n <button type=\"button\" className={css.generate} disabled={loading || !connected || (needModel && visibleModels.length === 0)} onClick={() => void submit()}>\n {loading ? tt('generating') : tt('generate')}\n </button>\n </div>\n\n <div className={css.result}>\n {error !== null ? <p className={css.error}>{error}</p> : null}\n {outputs.length === 0 ? <p className={css.empty}>{tt('result.empty')}</p> : (\n <>\n <p className={css.hint}>{tt('result.done', { count: outputs.length })}</p>\n <div className={css.audioList}>\n {outputs.map((audio, index) => (\n <div className={css.audioCard} key={audio.id}>\n {audio.voiceId !== undefined ? <p className={css.hint}>新音色 ID:{audio.voiceId}</p> : null}\n <audio className={css.audio} controls preload=\"metadata\" src={dataUrlOf(audio)} />\n <a className={css.download} href={dataUrlOf(audio)} download={`generated-${index + 1}.${audio.mime.split('/')[1]?.replace('mpeg', 'mp3') ?? 'mp3'}`}>下载</a>\n </div>\n ))}\n </div>\n </>\n )}\n </div>\n\n <aside className={css.history}>\n <div className={css.historyHeader}>\n <strong className={css.historyTitle}>{tt('history.title')}</strong>\n <button type=\"button\" onClick={clear} style={{ border: 0, background: 'none', cursor: 'pointer', color: 'inherit', fontSize: 12 }}>清空</button>\n </div>\n {entries.length === 0 ? <p className={css.historyEmpty}>{tt('history.empty')}</p> : (\n <div>\n {entries.map(entry => (\n <div className={css.historyItem} key={entry.id}>\n <div className={css.historyPrompt}>{entry.prompt}</div>\n <div className={css.historyMeta}>{entry.mode} · {entry.model}{entry.channel ? ` · ${entry.channel}` : ''}</div>\n {entry.audio.map((audio, index) => (\n <audio key={index} className={css.historyAudio} controls preload=\"none\" src={audio.url} />\n ))}\n </div>\n ))}\n </div>\n )}\n </aside>\n </div>\n </div>\n )\n}\n","/**\n * Panel view mounting for the AI 音频 panel.\n *\n * Like dsh-imagegen, the panel takes over the center column at the DOM level:\n * a container is appended inside the conversation grid item and a data\n * attribute on <html> hides/shows it.\n */\n\nimport { createRoot, type Root } from 'react-dom/client'\nimport type { AudiogenApi } from './api.ts'\nimport type { AudioGenController } from './controller.ts'\nimport { AudioGenPanel } from './AudioGenPanel.tsx'\nimport type { AudiogenScope } from './settings-scope.ts'\nimport css from './panel.module.css'\n\nexport const PANEL_VIEW_SELECTOR = '[data-dsh-audiogen-view]'\n\nconst CONVERSATION_COLUMN_SELECTOR = '[data-pane=\"conversation\"], [class*=\"centerCol\"]'\nconst ACTIVE_ATTR = 'data-dsh-audiogen-active'\nconst OTHER_ACTIVE_ATTRS = ['data-dsh-taskboard-active', 'data-dsh-ssh-active', 'data-dsh-imagegen-active']\nconst ACTIVATE_EVENT = 'dsh-panel-activate'\nconst PANEL_NAME = 'audiogen'\n\nfunction conversationColumn(): HTMLElement | undefined {\n return document.querySelector<HTMLElement>(CONVERSATION_COLUMN_SELECTOR) ?? undefined\n}\n\nexport function mountPanel(\n controller: AudioGenController,\n api: AudiogenApi,\n scope: AudiogenScope,\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 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.dshAudiogenView = ''\n container.className = css.view\n column.appendChild(container)\n root = createRoot(container)\n root.render(<AudioGenPanel api={api} scope={scope} />)\n }\n\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 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' || detail === 'imagegen') && controller.getSnapshot().panelOpen) {\n controller.close()\n }\n }\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 the entry row is injected at the DOM level after the shell's New Session\n * button. A MutationObserver self-heals when React re-renders.\n */\n\nimport type { AudioGenController } from './controller.ts'\nimport css from './panel.module.css'\n\nexport const ENTRY_SELECTOR = '[data-dsh-audiogen-entry]'\n\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\"><path d=\"M3 3.5h10v9H3z\"/><path d=\"M1.5 5.5v5\"/><path d=\"M14.5 5.5v5\"/><path d=\"M6 6.5l4 1.5-4 1.5z\"/></svg>'\n\nconst FAMILY_ENTRY_SELECTOR = '[data-dsh-taskboard-entry], [data-dsh-ssh-entry], [data-dsh-imagegen-entry], [data-dsh-audiogen-entry]'\n\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\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\nfunction createEntry(controller: AudioGenController, label: string, tooltip: string): HTMLButtonElement {\n const entry = document.createElement('button')\n entry.type = 'button'\n entry.dataset.dshAudiogenEntry = ''\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\nfunction placeEntry(root: HTMLElement, entry: HTMLButtonElement): boolean {\n const button = newSessionButton(root)\n if (button === undefined) return false\n if (entry.parentElement !== root) {\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\nexport function mountSidebarEntry(controller: AudioGenController, 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 const waitObserver = new MutationObserver(() => { tryPlace() })\n waitObserver.observe(document.body, { childList: true, subtree: true })\n\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 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 { AudiogenScope, 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 => ({\n alias: model.alias.trim(),\n id: model.id.trim() === '' ? model.alias.trim() : model.id.trim(),\n ...(model.category === undefined ? {} : { category: model.category }),\n }))\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: AudiogenScope) {\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: AudiogenScope): unknown {\n const view = scope.getSnapshot().value as { channels?: unknown } | undefined\n return Array.isArray(view?.channels) ? view.channels : []\n}\n","/**\n * The dsh-audiogen settings card.\n *\n * Registers into the official `settings.plugin.item` slot. It manages a list\n * of audio channels (each with API URL, per-channel secret, and model/voice\n * catalog), plus master switches.\n *\n * Channel management follows the DSH \"模型\" settings pattern: provider rows\n * with a status dot and 编辑/删除 actions, and two equal-width add actions\n * (「添加提供方」 / 「添加自定义提供方」) below. Both add and edit open the\n * same inline editor card — provider select, API key, 自定义设置 (API 地址)\n * and a 模型目录 with 「获取可用模型」 discovery and per-row model editing.\n */\n\nimport { useEffect, useMemo, 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, 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 { AudiogenScope } from './settings-scope.ts'\nimport { MODEL_API, PRESETS_API, type AudioModelCategory, type DiscoveredAudioModel, type ModelMapping, type PresetProviderView } from '../protocol.ts'\nimport type { AudioGenKey } from './locales.ts'\nimport css from './settings-card.module.css'\n\nexport interface AudioGenSettings {\n enabled?: boolean\n announceToAgent?: boolean\n allowAgentAudioGeneration?: boolean\n defaultModel?: string\n}\n\nexport interface AudioGenSettingsCardState extends CardShell {\n channels: ChannelsFormState\n enabled: CardFieldState\n announceToAgent: CardFieldState\n allowAgentAudioGeneration: CardFieldState\n defaultModel: CardFieldState\n}\n\nexport interface AudioGenSettingsCardFace extends CardActions {\n channels: ChannelsFormActions\n hooks: {\n audioGenSettingsCard: SnapshotStore<AudioGenSettingsCardState>\n }\n}\n\nexport class AudioGenSettingsCardController {\n private readonly form: CardForm<AudioGenSettings>\n private readonly channelsForm: ChannelsForm\n\n constructor(private readonly scope: AudiogenScope) {\n this.form = new CardForm(scope, [\n booleanField('enabled'),\n booleanField('announceToAgent'),\n booleanField('allowAgentAudioGeneration'),\n textField('defaultModel'),\n ])\n this.channelsForm = new ChannelsForm(scope)\n }\n\n private projection(): AudioGenSettingsCardState {\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 allowAgentAudioGeneration: this.form.field('allowAgentAudioGeneration'),\n defaultModel: this.form.field('defaultModel'),\n }\n }\n\n inject(): AudioGenSettingsCardFace {\n const cardStore = this.form.bind(() => this.projection())\n this.channelsForm.subscribe(() => { cardStore.set(this.projection()) })\n return {\n hooks: {\n audioGenSettingsCard: cardStore,\n },\n channels: this.channelsForm.actions(),\n ...this.form.actions(),\n }\n }\n}\n\nexport type AudioGenSettingsCardProps =\n PropsRuntime<'settings.plugin.item'>\n & PropsLocale<'dsh-audiogen'>\n & InjectFace<AudioGenSettingsCardFace>\n\n/** Which editor card is open. */\ntype EditorMode =\n | { kind: 'edit'; channelId: string }\n | { kind: 'add-provider' }\n | { kind: 'add-custom' }\n\nconst MODEL_CATEGORIES: Array<AudioModelCategory | undefined> = [\n undefined, 'tts', 'music', 'sfx', 'voice_design', 'voice_clone',\n]\n\nfunction newChannelId(): string {\n return `ch-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`\n}\n\n/** Strip a draft before staging: empty rows removed, aliases default to ids. */\nfunction cleanModels(models: ModelMapping[]): ModelMapping[] {\n const cleaned = models.map(model => {\n const alias = model.alias.trim()\n const id = model.id.trim() === '' ? alias : model.id.trim()\n if (alias === '' && id === '') return undefined\n return {\n alias: alias === '' ? id : alias,\n id,\n ...(model.category === undefined ? {} : { category: model.category }),\n } as ModelMapping | undefined\n }).filter((model): model is ModelMapping => model !== undefined)\n return [...new Map(cleaned.map(model => [model.alias, model])).values()]\n}\n\n/** Translate one key with interpolation (the injected `t` takes no values). */\nfunction tpl(\n t: (key: AudioGenKey) => string,\n key: AudioGenKey,\n values?: Record<string, string | number>,\n): string {\n let text = t(key)\n if (values === undefined) return text\n for (const [name, value] of Object.entries(values)) {\n text = text.replaceAll(`{${name}}`, String(value))\n }\n return text\n}\n\n/** One model row as the editor holds it (never empty—rows are removed). */\ninterface ModelRow extends ModelMapping {\n rowKey: string\n}\n\nfunction rowsOf(models: ModelMapping[]): ModelRow[] {\n return models.map((model, index) => ({ ...model, rowKey: `m-${index}-${model.alias}-${model.id}` }))\n}\n\n// ---------------------------------------------------------------------------\n// Channel editor card (add + edit share it)\n// ---------------------------------------------------------------------------\n\ninterface ChannelEditorProps {\n t: (key: AudioGenKey) => string\n writable: boolean\n /** 'edit' | 'add-provider' | 'add-custom' */\n mode: EditorMode\n /** The channel being edited (edit mode). */\n channel?: ChannelDraft\n /** Whether the edited channel currently holds a stored secret. */\n keyHeld: boolean\n /** Presets available for the 提供方 select (add-provider mode). */\n presets: PresetProviderView[]\n /** Whether the edited channel is the default channel. */\n initiallyDefault: boolean\n onCancel: () => void\n onSave: (channel: ChannelDraft, key: string | undefined, isDefault: boolean) => void\n}\n\nfunction ChannelEditor(props: ChannelEditorProps): React.JSX.Element {\n const { t, writable, mode, presets } = props\n\n const initialPresetId = mode.kind === 'add-provider' ? (presets[0]?.id ?? '') : ''\n const [presetId, setPresetId] = useState(initialPresetId)\n const invited = useMemo(\n () => (mode.kind === 'add-provider' ? presets.find(preset => preset.id === presetId) : undefined),\n [mode, presets, presetId],\n )\n\n // Draft fields. In add-provider mode the preset change re-seeds them.\n const [name, setName] = useState(props.channel?.name ?? (invited?.name ?? ''))\n const [url, setUrl] = useState(props.channel?.apiUrl ?? (invited?.apiUrl ?? ''))\n const [models, setModels] = useState<ModelRow[]>(rowsOf(props.channel?.models ?? invited?.models ?? []))\n const [key, setKey] = useState('')\n const [keyAction, setKeyAction] = useState<'none' | 'clear'>('none')\n const [isDefault, setIsDefault] = useState(props.initiallyDefault)\n\n const [discovering, setDiscovering] = useState(false)\n const [discoverError, setDiscoverError] = useState<string | null>(null)\n const [candidates, setCandidates] = useState<DiscoveredAudioModel[] | null>(null)\n const [picked, setPicked] = useState<ReadonlySet<string>>(new Set())\n const [sourceNote, setSourceNote] = useState<string | null>(null)\n\n const usePreset = (preset: PresetProviderView | undefined): void => {\n setPresetId(preset?.id ?? '')\n setName(preset?.name ?? '')\n setUrl(preset?.apiUrl ?? '')\n setModels(rowsOf(preset?.models ?? []))\n setKey('')\n setKeyAction('none')\n }\n\n const effectiveKeyHeld = props.keyHeld && keyAction !== 'clear'\n\n const save = (): void => {\n const currentId = props.channel?.id ?? newChannelId()\n const channel: ChannelDraft = {\n id: currentId,\n preset: mode.kind === 'edit' ? (props.channel?.preset ?? '') : (mode.kind === 'add-custom' ? '' : invited?.id ?? ''),\n name: name.trim(),\n apiUrl: url.trim(),\n models: cleanModels(models),\n }\n const stagedKey = key.trim() !== '' ? key.trim() : (keyAction === 'clear' ? '' : undefined)\n props.onSave(channel, stagedKey, isDefault)\n }\n\n const discoverable = url.trim() !== '' && (key.trim() !== '' || effectiveKeyHeld)\n\n const discover = async (): Promise<void> => {\n if (!discoverable) return\n setDiscovering(true)\n setDiscoverError(null)\n setSourceNote(null)\n try {\n const response = await fetch(MODEL_API.discover, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n channelId: props.channel?.id ?? 'preview',\n preset: mode.kind === 'add-provider' ? (invited?.id ?? '') : (props.channel?.preset ?? ''),\n apiUrl: url.trim(),\n ...(key.trim() !== '' ? { apiKey: key.trim() } : {}),\n }),\n })\n const body = await response.json() as { ok?: boolean; models?: DiscoveredAudioModel[]; message?: string; source?: string }\n if (body.ok !== true || body.models === undefined) {\n throw new Error(body.message ?? `HTTP ${response.status}`)\n }\n const known = new Set(models.map(model => model.id.trim()).filter(Boolean))\n const found = body.models\n .map(model => ({ ...model, id: model.id.trim() }))\n .filter(model => model.id !== '')\n if (found.length === 0) {\n setDiscoverError(t('channel.fetchEmpty'))\n return\n }\n setCandidates(found)\n setPicked(new Set(found.filter(model => !known.has(model.id)).map(model => model.id)))\n setSourceNote(body.source ?? null)\n } catch (error) {\n setDiscoverError(error instanceof Error ? error.message : String(error))\n } finally {\n setDiscovering(false)\n }\n }\n\n const closeCandidates = (): void => {\n setCandidates(null)\n setPicked(new Set())\n }\n\n const adoptCandidates = (): void => {\n if (candidates === null) return\n const existing = [...models]\n const byId = new Map(existing.map((model, index) => [model.id.trim(), { model, index }]))\n for (const candidate of candidates) {\n const id = candidate.id.trim()\n if (id === '' || !picked.has(id)) continue\n if (byId.has(id)) continue\n byId.set(id, { model: { rowKey: `m-${Date.now()}-${existing.length}`, alias: candidate.alias, id, ...(candidate.category === undefined ? {} : { category: candidate.category }) }, index: existing.length })\n existing.push(byId.get(id)!.model)\n }\n setModels(existing)\n closeCandidates()\n }\n\n const patchModel = (index: number, next: Partial<ModelMapping>): void => {\n setModels(models.map((model, at) => at === index ? { ...model, ...next } : model))\n }\n\n const presetPlaceholder = invited?.apiUrl ?? t('channel.apiUrlPlaceholder')\n\n return (\n <div className={css.channelEditor}>\n {mode.kind === 'add-provider' ? (\n <div className={css.field}>\n <label className={css.label} htmlFor=\"audiogen-editor-provider\">{t('channel.provider')}</label>\n <select\n id=\"audiogen-editor-provider\"\n className={css.select}\n value={presetId}\n disabled={!writable}\n onChange={event => usePreset(presets.find(preset => preset.id === event.target.value))}\n >\n {presets.map(preset => <option key={preset.id} value={preset.id}>{preset.name}</option>)}\n </select>\n {invited?.site !== undefined ? (\n <p className={css.sectionHint}>{t('channel.site')}:<a className={css.link} href={invited.site} target=\"_blank\" rel=\"noreferrer\">{invited.site}</a></p>\n ) : null}\n </div>\n ) : null}\n {mode.kind === 'add-custom' ? (\n <div className={css.field}>\n <span className={css.label}>{t('channel.provider')}</span>\n <p className={css.sectionHint}>{t('channel.providerCustom')} — {t('channel.providerCustomHint')}</p>\n </div>\n ) : null}\n {mode.kind === 'edit' ? (\n <div className={css.editorHeader}>\n <span className={css.editorTitle}>{props.channel?.name.trim() !== '' ? props.channel?.name : t('channels.untitled')}</span>\n <span className={css.editorTag}>{mode.kind === 'edit' ? t('channel.editTitle') : ''}</span>\n </div>\n ) : null}\n <div className={css.field}>\n <label className={css.label} htmlFor=\"audiogen-editor-name\">{t('channel.name')}</label>\n <input id=\"audiogen-editor-name\" className={css.input} value={name} placeholder={t('channel.namePlaceholder')} disabled={!writable} onChange={event => setName(event.target.value)} />\n </div>\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor=\"audiogen-editor-key\">{t('channel.apiKey')}</label>\n {effectiveKeyHeld && key.trim() === '' ? (\n <button type=\"button\" className={css.reset} disabled={!writable} onClick={() => { setKeyAction('clear'); setKey('') }}>\n {t('channel.clearKey')}\n </button>\n ) : null}\n </div>\n <input\n id=\"audiogen-editor-key\"\n className={css.input}\n type=\"password\"\n value={key}\n autoComplete=\"off\"\n placeholder={effectiveKeyHeld ? '••••••••' : ''}\n disabled={!writable}\n onChange={event => { setKey(event.target.value); if (event.target.value !== '') setKeyAction('none') }}\n />\n <p className={css.sectionHint}>{effectiveKeyHeld ? t('channel.apiKeyStoredHint') : t('channel.apiKeyHint')}</p>\n </div>\n <details className={css.customSettings}>\n <summary className={css.customSettingsSummary}>{t('channel.customSettings')}</summary>\n <div className={css.customSettingsBody}>\n <div className={css.field}>\n <label className={css.label} htmlFor=\"audiogen-editor-url\">{t('channel.apiUrl')}</label>\n <input\n id=\"audiogen-editor-url\"\n className={css.input}\n type=\"text\"\n value={url}\n placeholder={presetPlaceholder}\n disabled={!writable}\n onChange={event => setUrl(event.target.value)}\n />\n <p className={css.sectionHint}>{t('channel.apiUrlHint')}</p>\n </div>\n </div>\n </details>\n <ModelCatalog\n t={t}\n writable={writable}\n models={models}\n discoverable={discoverable}\n discovering={discovering}\n discoverError={discoverError}\n candidates={candidates}\n picked={picked}\n sourceNote={sourceNote}\n onPatchModel={patchModel}\n onRemoveModel={index => setModels(models.filter((_model, at) => at !== index))}\n onAddModel={() => setModels([...models, { rowKey: `m-${Date.now()}-${models.length}`, alias: '', id: '' }])}\n onDiscover={() => void discover()}\n onTogglePicked={id => {\n setPicked(current => {\n const next = new Set(current)\n if (!next.delete(id)) next.add(id)\n return next\n })\n }}\n onToggleAllPicked={() => {\n setPicked(current => (candidates !== null && candidates.length > 0 && candidates.every(candidate => current.has(candidate.id)))\n ? new Set()\n : new Set((candidates ?? []).map(candidate => candidate.id)))\n }}\n onAdopt={() => adoptCandidates()}\n onCloseCandidates={closeCandidates}\n />\n <label className={css.field}>\n <span className={css.label}>\n <input type=\"checkbox\" checked={isDefault} disabled={!writable} onChange={event => setIsDefault(event.target.checked)} /> {t('channel.default')}\n </span>\n </label>\n <div className={css.editorFooter}>\n <button type=\"button\" className={css.discard} onClick={props.onCancel}>{t('channel.cancel')}</button>\n <button type=\"button\" className={css.save} onClick={save}>{t('channel.save')}</button>\n </div>\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Model catalog (目录) inside the channel editor\n// ---------------------------------------------------------------------------\n\ninterface ModelCatalogProps {\n t: (key: AudioGenKey) => string\n writable: boolean\n models: ModelRow[]\n discoverable: boolean\n discovering: boolean\n discoverError: string | null\n candidates: DiscoveredAudioModel[] | null\n picked: ReadonlySet<string>\n sourceNote: string | null\n onPatchModel: (index: number, next: Partial<ModelMapping>) => void\n onRemoveModel: (index: number) => void\n onAddModel: () => void\n onDiscover: () => void\n onTogglePicked: (id: string) => void\n onToggleAllPicked: () => void\n onAdopt: () => void\n onCloseCandidates: () => void\n}\n\nfunction ModelCatalog(props: ModelCatalogProps): React.JSX.Element {\n const { t, writable, models, discoverable, discovering, candidates, picked } = props\n const allPicked = candidates !== null && candidates.length > 0 && candidates.every(candidate => picked.has(candidate.id))\n return (\n <section className={css.modelCatalog} aria-label={t('channel.modelsTitle')}>\n <div className={css.modelCatalogHead}>\n <div>\n <span className={css.modelCatalogTitle}>{t('channel.modelsTitle')}</span>\n <span className={css.modelCatalogMeta}>\n {models.length > 0 ? tpl(t, 'channel.modelsCount', { n: models.length }) : t('channel.modelsNone')}\n </span>\n </div>\n <button\n type=\"button\"\n className={css.linkButton}\n disabled={!writable || discovering || !discoverable}\n title={discoverable ? undefined : t('channel.discoverNeedsUrlKey')}\n onClick={props.onDiscover}\n >\n {discovering ? t('channel.fetchingModels') : t('channel.fetchModels')}\n </button>\n </div>\n {models.length === 0 ? <p className={css.modelEmpty}>{t('channel.modelsEmpty')}</p> : (\n <ul className={css.modelRows}>\n {models.map((model, index) => (\n <li key={`${model.rowKey}-${index}`} className={css.modelRow}>\n <input\n className={`${css.input} ${css.modelInput}`}\n type=\"text\"\n value={model.alias}\n placeholder={t('channel.modelAlias')}\n aria-label={`${t('channel.modelAlias')} ${index + 1}`}\n disabled={!writable}\n onChange={event => props.onPatchModel(index, { alias: event.target.value })}\n />\n <span className={css.modelArrow} aria-hidden=\"true\">→</span>\n <input\n className={`${css.input} ${css.modelInput}`}\n type=\"text\"\n value={model.id}\n placeholder={t('channel.modelId')}\n aria-label={`${t('channel.modelId')} ${index + 1}`}\n disabled={!writable}\n onChange={event => props.onPatchModel(index, { id: event.target.value })}\n />\n <select\n className={`${css.select} ${css.modelCategorySelect}`}\n value={model.category ?? ''}\n aria-label={`${t('channel.modelCategory')} ${index + 1}`}\n disabled={!writable}\n onChange={event => {\n const value = event.target.value as AudioModelCategory | ''\n props.onPatchModel(index, value === '' ? { category: undefined } : { category: value })\n }}\n >\n {MODEL_CATEGORIES.map(category => (\n <option key={category ?? 'auto'} value={category ?? ''}>{category === undefined ? t('channel.category.auto') : t(`channel.category.${category}`)}</option>\n ))}\n </select>\n <button\n type=\"button\"\n className={css.modelRowRemove}\n aria-label={t('channel.removeModel')}\n disabled={!writable}\n onClick={() => props.onRemoveModel(index)}\n >\n ×\n </button>\n </li>\n ))}\n </ul>\n )}\n <div className={css.modelCatalogTools}>\n <button type=\"button\" className={css.addModel} disabled={!writable} onClick={props.onAddModel}>\n {t('channel.addModel')}\n </button>\n </div>\n {props.sourceNote !== null && props.candidates !== null ? (\n <p className={css.detectOk}>{tpl(t, 'channel.discoverSource', { source: props.sourceNote })}</p>\n ) : null}\n {props.discoverError !== null ? <p className={css.failed}>{props.discoverError}</p> : null}\n {candidates === null ? null : (\n <div className={css.candidatePanel}>\n <div className={css.candidateHead}>\n <span className={css.candidateTitle}>{tpl(t, 'channel.candidates', { n: candidates.length })}</span>\n <button type=\"button\" className={css.linkButton} onClick={props.onToggleAllPicked}>\n {allPicked ? t('channel.clearSelection') : t('channel.selectAll')}\n </button>\n </div>\n <ul className={css.candidateList}>\n {candidates.map(candidate => (\n <li key={candidate.id} className={css.candidate}>\n <label className={css.candidateLabel}>\n <input\n type=\"checkbox\"\n checked={picked.has(candidate.id)}\n disabled={models.some(model => model.id.trim() === candidate.id)}\n onChange={() => props.onTogglePicked(candidate.id)}\n />\n <span className={css.candidateId}>{candidate.alias === candidate.id ? candidate.id : `${candidate.alias}(${candidate.id})`}</span>\n {candidate.category !== undefined ? <span className={css.modelBadge}>{t(`channel.category.${candidate.category}`)}</span> : null}\n </label>\n </li>\n ))}\n </ul>\n <div className={css.candidateActions}>\n <button type=\"button\" className={css.discard} onClick={props.onCloseCandidates}>{t('channel.cancel')}</button>\n <button type=\"button\" className={css.save} onClick={props.onAdopt}>\n {tpl(t, 'channel.adoptSelected', { n: Array.from(picked).length })}\n </button>\n </div>\n </div>\n )}\n </section>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Card\n// ---------------------------------------------------------------------------\n\nexport function AudioGenSettingsCard(props: AudioGenSettingsCardProps) {\n const { t } = props\n const state = props.useAudioGenSettingsCard(snapshot => snapshot)\n const [open, setOpen] = useState(false)\n const [editor, setEditor] = useState<EditorMode | null>(null)\n const [presets, setPresets] = useState<PresetProviderView[]>([])\n const [presetLoading, setPresetLoading] = useState(false)\n const [presetError, setPresetError] = useState<string | null>(null)\n const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null)\n\n const channels = state.channels.channels\n const editingChannel = editor !== null && editor.kind === 'edit'\n ? channels.find(channel => channel.id === editor.channelId)\n : undefined\n\n useEffect(() => {\n if (editor?.kind === 'add-provider' && presets.length === 0 && presetError === null && !presetLoading) {\n setPresetLoading(true)\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 .finally(() => setPresetLoading(false))\n }\n }, [editor, presets.length, presetError, presetLoading])\n\n if (!state.available) return null\n\n const blocked = !state.dirty || state.invalid || state.saving || state.channels.saving\n\n const closeEditor = (): void => { setEditor(null) }\n\n const saveEditor = (channel: ChannelDraft, key: string | undefined, isDefault: boolean): void => {\n const exists = channels.some(candidate => candidate.id === channel.id)\n const next = exists\n ? channels.map(candidate => candidate.id === channel.id ? channel : candidate)\n : [...channels, channel]\n props.channels.setChannels(next)\n // key === undefined: no staged change; key === '': clear; otherwise set.\n if (key !== undefined) props.channels.setChannelKey(channel.id, key)\n if (isDefault) props.channels.setDefaultChannel(channel.id)\n closeEditor()\n }\n\n const removeChannel = (channel: ChannelDraft): void => {\n const isDefault = channel.id === state.channels.defaultChannelId\n const next = channels.filter(candidate => candidate.id !== channel.id)\n props.channels.setChannels(next)\n if (isDefault && next.length > 0) {\n props.channels.setDefaultChannel(next[0]!.id)\n }\n setConfirmDeleteId(null)\n if (editor?.kind === 'edit' && editor.channelId === channel.id) closeEditor()\n }\n\n const openAddProvider = (): void => {\n setPresetError(null)\n setEditor({ kind: 'add-provider' })\n }\n\n const openAddCustom = (): void => {\n setPresetError(null)\n setEditor({ kind: 'add-custom' })\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')}: ${t('settings.title')}`}\n onClick={() => { setOpen(!open) }}\n >\n <span className={css.headText}>\n <span className={css.name}>{t('settings.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 ? null : (\n <div className={css.body}>\n {!state.writable ? <p className={css.readOnly} role=\"status\">{t('settings.readOnly')}</p> : null}\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 ? <p className={css.channelEmpty}>{t('channels.empty')}</p> : (\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.confirm')}: {channel.name || t('channels.untitled')}</span>\n <button type=\"button\" className={css.channelDanger} disabled={!state.writable} onClick={() => removeChannel(channel)}>{t('channels.confirm')}</button>\n <button type=\"button\" className={css.channelAction} 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={!state.writable} onClick={() => { setEditor({ kind: 'edit', channelId: 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 <span className={css.channelHost}>{channel.apiUrl || '(no url)'}</span>\n <span className={css.channelBadge} data-warn={!keyHeld || channel.models.length === 0 ? '' : undefined}>\n {keyHeld ? t('channels.keySet') : t('channels.keyMissing')}\n {' · '}\n {channel.models.length > 0 ? t('channels.modelCount', { n: channel.models.length }) : t('channels.noModels')}\n </span>\n </span>\n </button>\n <button type=\"button\" className={css.channelAction} onClick={() => { setEditor({ kind: 'edit', channelId: 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 {presetError !== null ? <p className={css.failed}>{presetError}</p> : null}\n <div className={css.channelAddRow}>\n <button type=\"button\" className={css.channelAdd} disabled={!state.writable} onClick={openAddProvider}>\n {presetLoading ? t('channels.addProviderLoading') : t('channels.addProvider')}\n </button>\n <button type=\"button\" className={css.channelAdd} disabled={!state.writable} onClick={openAddCustom}>\n {t('channels.addCustom')}\n </button>\n </div>\n {editor !== null ? (\n editor.kind === 'add-provider' && presets.length === 0 && presetError === null ? (\n <p className={css.sectionHint}>{presetLoading ? t('channels.addProviderLoading') : t('channels.addProviderFailed')}</p>\n ) : (\n <div className={css.editorWrap}>\n <ChannelEditor\n key={editor.kind === 'edit' ? `edit-${editor.channelId}` : editor.kind}\n t={t}\n writable={state.writable}\n mode={editor}\n channel={editingChannel}\n keyHeld={editor.kind === 'edit' ? state.channels.keySet[editor.channelId] === true : false}\n presets={presets}\n initiallyDefault={editor.kind === 'edit' ? editor.channelId === state.channels.defaultChannelId : channels.length === 0}\n onCancel={closeEditor}\n onSave={saveEditor}\n />\n </div>\n )\n ) : null}\n </section>\n\n <div className={css.field}>\n <label className={css.label}>\n <input type=\"checkbox\" checked={state.enabled.text === 'true' || state.enabled.text === ''} disabled={!state.writable} onChange={event => props.edit('enabled', String(event.target.checked))} /> {t('settings.enabled')}\n </label>\n </div>\n <div className={css.field}>\n <label className={css.label}>\n <input type=\"checkbox\" checked={state.announceToAgent.text === 'true' || state.announceToAgent.text === ''} disabled={!state.writable} onChange={event => props.edit('announceToAgent', String(event.target.checked))} /> {t('settings.announceToAgent')}\n </label>\n </div>\n <div className={css.field}>\n <label className={css.label}>\n <input type=\"checkbox\" checked={state.allowAgentAudioGeneration.text === 'true' || state.allowAgentAudioGeneration.text === ''} disabled={!state.writable} onChange={event => props.edit('allowAgentAudioGeneration', String(event.target.checked))} /> {t('settings.allowAgentAudio')}\n </label>\n </div>\n <div className={css.footer}>\n {state.failed ? <p className={css.failed}>保存失败</p> : null}\n <button type=\"button\" className={css.discard} disabled={!state.dirty || state.saving} onClick={() => props.discard()}>{t('settings.discard')}</button>\n <button type=\"button\" className={css.save} disabled={blocked} onClick={() => { void props.save(); void props.channels.commit() }}>\n {state.saving ? t('settings.saving') : t('settings.save')}\n </button>\n </div>\n </div>\n )}\n </li>\n )\n}\n","/**\n * Inline renderer for audio-generation tool results.\n *\n * The model-facing tool result is a JSON text envelope with same-origin audio\n * URLs; this view turns it into a small audio-player card.\n */\n\nimport type { ClientContext, SessionId } from '@deepseek-ai/dsh-client-runtime/client'\nimport { useEffect, useMemo, useState } from 'react'\nimport css from './audio-toolview.module.css'\n\nexport interface AudioToolViewOwnerProps {\n callId: string\n toolName: string\n block: unknown\n cwd?: string\n home?: string\n openFile: (path: string) => void\n inspect?: () => void\n}\n\ninterface AudioFileRef {\n id?: string\n url: string\n mime: string\n bytes: number\n}\n\ninterface AudioToolViewProps extends AudioToolViewOwnerProps {\n sessionId: SessionId\n}\n\nfunction isSettled(block: unknown): block is { content?: Array<{ type: string; text?: string }>; isError?: boolean } {\n return typeof block === 'object' && block !== null && 'content' in block\n}\n\nfunction textOf(block: unknown): string {\n if (!isSettled(block)) return ''\n return (block.content ?? [])\n .filter(content => content.type === 'text' && typeof content.text === 'string')\n .map(content => content.text as string)\n .join('\\n')\n}\n\nfunction parseResult(block: unknown): { status: string; message: string; audio: AudioFileRef[]; error?: string } {\n const text = textOf(block)\n if (text === '') return { status: 'running', message: '正在生成音频…', audio: [] }\n try {\n const parsed = JSON.parse(text) as { status?: string; message?: string; audio?: AudioFileRef[]; error?: string }\n return {\n status: parsed.status ?? 'completed',\n message: parsed.message ?? '',\n audio: Array.isArray(parsed.audio) ? parsed.audio.filter((item): item is AudioFileRef => {\n return typeof item === 'object' && item !== null && typeof (item as AudioFileRef).url === 'string'\n }) : [],\n ...(typeof parsed.error === 'string' ? { error: parsed.error } : {}),\n }\n } catch {\n return { status: 'completed', message: text, audio: [] }\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 mimeExt(mime: string): string {\n if (mime.includes('wav')) return 'wav'\n if (mime.includes('flac')) return 'flac'\n if (mime.includes('ogg')) return 'ogg'\n if (mime.includes('mp4') || mime.includes('m4a')) return 'm4a'\n return 'mp3'\n}\n\nexport function registerAudioToolviews(ctx: ClientContext): void {\n const AudioToolView = (props: AudioToolViewProps): React.JSX.Element => {\n const result = useMemo(() => parseResult(props.block), [props.block])\n const [active, setActive] = useState<string | null>(null)\n useEffect(() => { setActive(null) }, [props.callId])\n const title = props.toolName === 'generate_audio' ? '生成音频' : props.toolName\n return (\n <section className={css.root} data-state={result.status} data-tool={props.toolName}>\n <header className={css.header}>\n <span className={css.icon} aria-hidden=\"true\">♫</span>\n <strong>{title}</strong>\n <span className={css.status}>{statusLabel(result.status)}</span>\n </header>\n {result.message !== '' && <p className={css.message}>{result.message}</p>}\n {result.error !== undefined && <p className={css.error}>{result.error}</p>}\n {result.audio.length > 0 && (\n <div className={css.audios}>\n {result.audio.map((audio, index) => (\n <div className={css.audioRow} key={audio.id ?? audio.url}>\n <audio\n className={css.audio}\n controls\n preload=\"metadata\"\n src={audio.url}\n onPlay={() => setActive(audio.url)}\n />\n <a className={css.download} href={audio.url} download={`generated-${index + 1}.${mimeExt(audio.mime)}`}>\n 下载\n </a>\n </div>\n ))}\n </div>\n )}\n {result.audio.length === 0 && result.status !== 'running' && <p className={css.empty}>未返回可播放的音频。</p>}\n </section>\n )\n }\n\n ctx.slots.inject('tool.call.toolview', function* () {\n yield ctx.slots.register({ name: 'tool.call.toolview', key: 'generate_audio' }, AudioToolView)\n })\n}\n","/**\n * Browser-half entry for dsh-audiogen.\n *\n * Registers locale dictionaries, the settings card (Settings → Plugins → AI\n * 音频), and mounts the sidebar entry + generation panel. DOM mounting\n * failures are logged, never thrown.\n */\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport { AudiogenApi } from './api.ts'\nimport { AudioGenController } from './controller.ts'\nimport { tt } from './helpers.ts'\nimport { en, zh, type AudioGenKey } from './locales.ts'\nimport { mountPanel } from './mount.tsx'\nimport { mountSidebarEntry } from './sidebar-entry.ts'\nimport { AudioGenSettingsCard, AudioGenSettingsCardController } from './SettingsCard.tsx'\nimport { bindAudiogenScope, type AudiogenScope } from './settings-scope.ts'\nimport { registerAudioToolviews } from './audio-toolview.tsx'\n\nconst NS = 'dsh-audiogen'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n 'dsh-audiogen': AudioGenKey\n }\n\n interface SlotMap {\n 'settings.plugin.item': { kind: 'keyed'; scope: 'root'; owner: AudioGenPluginItemOwnerProps }\n 'tool.call.toolview': { kind: 'keyed'; scope: 'session'; owner: AudioToolViewOwnerProps }\n }\n}\n\nexport interface AudioGenPluginItemOwnerProps {\n children?: never\n}\n\nexport type AudioToolViewOwnerProps = {\n callId: string\n toolName: string\n block: unknown\n cwd?: string\n home?: string\n openFile: (path: string) => void\n inspect?: () => void\n}\n\nexport const inject = ['slots', 'locale', 'connection', 'sessions']\n\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-audiogen: dictionaries')\n registerAudioToolviews(ctx)\n\n const connection = ctx.get('connection') as ConnectionHandle | undefined\n const loopback = connection?.isLoopback === true\n const scope: AudiogenScope = bindAudiogenScope(loopback\n ? (input, init) => fetch(input, init)\n : () => { throw new Error('settings bridge is loopback-only') })\n\n ctx.effect(() => {\n const disposers = [\n ctx.on('connection/reset', () => { void scope.load() }),\n ]\n return () => { for (const dispose of disposers) dispose() }\n }, 'dsh-audiogen: settings scope invalidation')\n\n const settingsCard = new AudioGenSettingsCardController(scope)\n ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({\n name: 'settings.plugin.item',\n key: 'dsh-audiogen',\n locale: NS,\n inject: () => settingsCard.inject(),\n }, AudioGenSettingsCard))\n\n let uiDisposer: (() => void) | undefined\n const mountUi = (): void => {\n if (uiDisposer !== undefined) return\n const controller = new AudioGenController()\n const api = new AudiogenApi()\n const disposers: Array<() => void> = []\n try {\n disposers.push(mountSidebarEntry(controller, tt('entry.label'), tt('entry.tooltip')))\n disposers.push(mountPanel(controller, api, scope))\n } catch (error) {\n console.warn('[dsh-audiogen] mount failed:', error)\n }\n uiDisposer = () => {\n for (const dispose of disposers.splice(0)) dispose()\n uiDisposer = undefined\n }\n }\n const syncEnabled = (): void => {\n const snapshot = scope.getSnapshot()\n const enabled = snapshot.status === 'ready'\n ? snapshot.value?.enabled ?? true\n : snapshot.status === 'unavailable'\n if (enabled) mountUi()\n else uiDisposer?.()\n }\n scope.subscribe(syncEnabled)\n syncEnabled()\n}\n"],"mappings":"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"}
|