@logictan/dsh-imagegen 2.0.3 → 2.0.5

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 CHANGED
@@ -6,6 +6,7 @@ window.__ModuleLoader__.load({
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
7
  let react = require("react");
8
8
  let _deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
9
+ let _logictan_dsh_plugins_shared_client_client = require("@logictan/dsh-plugins-shared-client/client");
9
10
  let react_jsx_runtime = require("react/jsx-runtime");
10
11
  //#region src/client/locales.ts
11
12
  /**
@@ -420,8 +421,8 @@ window.__ModuleLoader__.load({
420
421
  "settings.addModelConfirm": "添加",
421
422
  "settings.removeModel": "移除模型",
422
423
  "settings.optional": "可选",
423
- "settings.moreOptions": "更多设置",
424
424
  "settings.promptEnhanceTitle": "提示词增强模型",
425
+ "settings.scalarsTitle": "插件开关与对话模型",
425
426
  "settings.promptEnhanceHint": "用于将简短描述扩写为更完整的生图提示词;留空的地址和密钥会复用生图配置。",
426
427
  "settings.promptApiUrl": "对话 API 地址(可选)",
427
428
  "settings.promptApiUrlHint": "OpenAI 兼容基址;留空则复用图像 API 地址。",
@@ -442,9 +443,6 @@ window.__ModuleLoader__.load({
442
443
  "settings.allowAgentImageGenerationHint": "默认开启。关闭后,Agent 无法提交、查询或取消生图任务;侧边栏工作台不受影响。",
443
444
  "settings.enabled": "启用插件",
444
445
  "settings.enabledHint": "关闭后生图面板不可用(设置卡片始终可用)",
445
- "settings.save": "保存",
446
- "settings.saving": "保存中…",
447
- "settings.discard": "放弃修改",
448
446
  "settings.unsaved": "有未保存的修改",
449
447
  "settings.saveFailed": "保存失败,请重试",
450
448
  "settings.readOnly": "当前设置文档为只读,无法保存。",
@@ -1162,8 +1160,8 @@ window.__ModuleLoader__.load({
1162
1160
  "settings.addModelConfirm": "Add",
1163
1161
  "settings.removeModel": "Remove model",
1164
1162
  "settings.optional": "Optional",
1165
- "settings.moreOptions": "More settings",
1166
1163
  "settings.promptEnhanceTitle": "Prompt enhancement model",
1164
+ "settings.scalarsTitle": "Plugin switches and chat model",
1167
1165
  "settings.promptEnhanceHint": "Expands short requests into complete image prompts. Blank URL and key reuse the image API configuration.",
1168
1166
  "settings.promptApiUrl": "Chat API URL (optional)",
1169
1167
  "settings.promptApiUrlHint": "OpenAI-compatible base URL. Leave blank to reuse the image API URL.",
@@ -1184,9 +1182,6 @@ window.__ModuleLoader__.load({
1184
1182
  "settings.allowAgentImageGenerationHint": "On by default. When off, agents cannot submit, query, or cancel image tasks; the sidebar studio remains available.",
1185
1183
  "settings.enabled": "Enable plugin",
1186
1184
  "settings.enabledHint": "When off, the generation studio is unavailable (this card stays available)",
1187
- "settings.save": "Save",
1188
- "settings.saving": "Saving…",
1189
- "settings.discard": "Discard",
1190
1185
  "settings.unsaved": "Unsaved changes",
1191
1186
  "settings.saveFailed": "Save failed, please retry",
1192
1187
  "settings.readOnly": "The settings document is read-only; saving is disabled.",
@@ -1905,8 +1900,8 @@ window.__ModuleLoader__.load({
1905
1900
  "settings.addModelConfirm": "Добавить",
1906
1901
  "settings.removeModel": "Удалить модель",
1907
1902
  "settings.optional": "необязательно",
1908
- "settings.moreOptions": "Дополнительно",
1909
1903
  "settings.promptEnhanceTitle": "Модель улучшения промптов",
1904
+ "settings.scalarsTitle": "Переключатели плагина и модель чата",
1910
1905
  "settings.promptEnhanceHint": "Разворачивает краткое описание в полноценный промпт; пустые адрес и ключ наследуют настройки генерации.",
1911
1906
  "settings.promptApiUrl": "Адрес диалогового API (необязательно)",
1912
1907
  "settings.promptApiUrlHint": "OpenAI-совместимая база; если пусто — используется адрес API генерации.",
@@ -1927,9 +1922,6 @@ window.__ModuleLoader__.load({
1927
1922
  "settings.allowAgentImageGenerationHint": "Включено по умолчанию. Выключено — агенты не могут создавать, смотреть или отменять задачи; боковая панель работает.",
1928
1923
  "settings.enabled": "Включить плагин",
1929
1924
  "settings.enabledHint": "Выключено — панель генерации недоступна (карточка настроек работает всегда)",
1930
- "settings.save": "Сохранить",
1931
- "settings.saving": "Сохраняем…",
1932
- "settings.discard": "Отменить правки",
1933
1925
  "settings.unsaved": "Есть несохранённые правки",
1934
1926
  "settings.saveFailed": "Не удалось сохранить, попробуйте ещё раз",
1935
1927
  "settings.readOnly": "Документ настроек сейчас только для чтения, сохранить нельзя.",
@@ -2332,37 +2324,6 @@ window.__ModuleLoader__.load({
2332
2324
  * pattern the dsh-web-ui family cards use (this package must not depend on a
2333
2325
  * sibling UI package).
2334
2326
  */
2335
- /** A free-text field. An empty draft clears the field. */
2336
- function textField(field) {
2337
- return {
2338
- field,
2339
- format: (value) => typeof value === "string" ? value : "",
2340
- parse: (text) => {
2341
- const trimmed = text.trim();
2342
- return trimmed === "" ? { kind: "clear" } : {
2343
- kind: "set",
2344
- value: trimmed
2345
- };
2346
- }
2347
- };
2348
- }
2349
- /** A boolean field, edited through true/false draft text. */
2350
- function booleanField(field) {
2351
- return {
2352
- field,
2353
- format: (value) => typeof value === "boolean" ? String(value) : "",
2354
- parse: (text) => {
2355
- if (text === "true") return {
2356
- kind: "set",
2357
- value: true
2358
- };
2359
- if (text === "false") return {
2360
- kind: "set",
2361
- value: false
2362
- };
2363
- }
2364
- };
2365
- }
2366
2327
  /**
2367
2328
  * A secret field (role('secret') in the namespace schema). The stored value is
2368
2329
  * never rendered or returned by the redacted wire view, so:
@@ -2990,7 +2951,7 @@ window.__ModuleLoader__.load({
2990
2951
  */
2991
2952
  /** Settings namespace this plugin owns (host settings seam + bridge). */
2992
2953
  const IMAGEGEN_SETTINGS_NAMESPACE = "imagegen";
2993
- /** Same-origin route family (loopback-only, mirroring the dsh-ssh fence). */
2954
+ /** Same-origin route family (fenced by the composition's connection service). */
2994
2955
  const SETTINGS_API = {
2995
2956
  describe: "/api/dsh-imagegen/settings/describe",
2996
2957
  mutate: "/api/dsh-imagegen/settings/mutate"
@@ -3004,7 +2965,7 @@ window.__ModuleLoader__.load({
3004
2965
  const IMAGE_MODEL_API = { models: "/api/dsh-imagegen/image-models" };
3005
2966
  /** Host-served built-in provider catalog (channels the user can instantiate). */
3006
2967
  const PRESETS_API = "/api/dsh-imagegen/presets";
3007
- /** Loopback-only image reader for Agent tool-result previews. */
2968
+ /** Image reader for Agent tool-result previews (fenced by the connection service). */
3008
2969
  const AGENT_IMAGE_API = "/api/dsh-imagegen/agent-image";
3009
2970
  //#endregion
3010
2971
  //#region src/client/use-language.ts
@@ -3020,7 +2981,7 @@ window.__ModuleLoader__.load({
3020
2981
  }
3021
2982
  //#endregion
3022
2983
  //#region \0dsh-css:/home/runner/work/dsh-plugins/dsh-plugins/packages/dsh-imagegen/src/client/settings-card.module.css.mjs
3023
- const css$1 = "._5JdLea_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}._5JdLea_card:hover{border-color:var(--dsw-alias-label-dimmed)}._5JdLea_card:has(._5JdLea_body){background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}._5JdLea_header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}._5JdLea_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}._5JdLea_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}._5JdLea_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}._5JdLea_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}._5JdLea_chevron,._5JdLea_chevronOpen{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}._5JdLea_chevronOpen{transform:rotate(180deg)}._5JdLea_pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}._5JdLea_body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}._5JdLea_versionRow{border-bottom:1px solid var(--dsw-alias-border-l2);justify-content:space-between;align-items:center;gap:12px;padding:12px 0;display:flex}._5JdLea_versionLabel{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:1.5}._5JdLea_versionValue{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);font-family:var(--dsw-font-family-mono,monospace);border-radius:999px;padding:1px 8px;font-size:12px;line-height:1.5}._5JdLea_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}._5JdLea_field+._5JdLea_field{border-top:1px solid var(--dsw-alias-border-l2)}._5JdLea_head{align-items:center;gap:8px;display:flex}._5JdLea_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}._5JdLea_badges{align-items:center;gap:8px;display:inline-flex}._5JdLea_badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}._5JdLea_reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}._5JdLea_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}._5JdLea_reset:disabled{cursor:default;opacity:.5}._5JdLea_input,._5JdLea_select{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;outline:none;padding:0 12px;font-size:13px;line-height:1.5}._5JdLea_input:focus-visible,._5JdLea_select:focus-visible{border-color:var(--dsw-alias-brand-primary)}._5JdLea_input:disabled,._5JdLea_select:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}._5JdLea_inputInvalid{border:1px solid var(--dsw-alias-label-error);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;outline:none;padding:0 12px;font-size:13px;line-height:1.5}._5JdLea_textarea,._5JdLea_textareaInvalid{resize:vertical;background:var(--dsw-alias-bg-layer-3);min-height:70px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;outline:none;padding:8px 12px;font-size:13px;line-height:1.5}._5JdLea_textarea{border:1px solid var(--dsw-alias-border-l2)}._5JdLea_textareaInvalid{border:1px solid var(--dsw-alias-label-error)}._5JdLea_textarea:focus-visible{border-color:var(--dsw-alias-brand-primary)}._5JdLea_textarea:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}._5JdLea_hint,._5JdLea_invalid{margin:0;font-size:12px;line-height:1.5}._5JdLea_hint{color:var(--dsw-alias-label-tertiary)}._5JdLea_invalid{color:var(--dsw-alias-label-error)}._5JdLea_readOnly,._5JdLea_notExposed{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}._5JdLea_sectionDivider{background:var(--dsw-alias-border-l2);height:1px;margin:18px 0 14px}._5JdLea_sectionTitle{color:var(--dsw-alias-label-primary);margin:0;font-size:14px;line-height:1.4}._5JdLea_sectionHint{color:var(--dsw-alias-label-tertiary);margin:-4px 0 2px;font-size:12px;line-height:1.5}._5JdLea_modelSection{padding:2px 0 14px}._5JdLea_sectionHeader{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}._5JdLea_sectionHeader ._5JdLea_sectionHint{max-width:430px}._5JdLea_modelSummary{flex-wrap:wrap;align-items:center;gap:6px;margin-top:12px;display:flex}._5JdLea_modelChip{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);max-width:100%;color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-family-mono,monospace);border-radius:6px;align-items:center;gap:5px;padding:3px 5px 3px 8px;font-size:12px;line-height:1.5;display:inline-flex}._5JdLea_modelChip>span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}._5JdLea_modelChip button{appearance:none;width:18px;height:18px;color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:0;border-radius:4px;padding:0;line-height:18px}._5JdLea_modelChip button:hover:not(:disabled){color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-module-platform)}._5JdLea_modelChip button:disabled{cursor:default;opacity:.45}._5JdLea_addModel{appearance:none;border:1px dashed var(--dsw-alias-border-l2);min-height:28px;color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:0 9px;font-size:12px}._5JdLea_addModel:hover:not(:disabled){color:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}._5JdLea_addModel:disabled{opacity:.45;cursor:default}._5JdLea_manualModelRow{gap:8px;margin-top:10px;display:flex}._5JdLea_manualModelRow ._5JdLea_input{flex:1;min-width:0}._5JdLea_disclosure{appearance:none;border:0;border-top:1px solid var(--dsw-alias-border-l2);width:100%;color:var(--dsw-alias-label-primary);font:inherit;text-align:left;cursor:pointer;background:0 0;align-items:center;gap:8px;padding:13px 0;font-size:13px;font-weight:500;display:flex}._5JdLea_disclosure>span:nth-child(2){color:var(--dsw-alias-label-tertiary);margin-left:auto;font-size:12px;font-weight:400}._5JdLea_disclosure>span:last-child{color:var(--dsw-alias-label-tertiary)}._5JdLea_disclosure:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}._5JdLea_optionalContent{padding:0 0 8px}._5JdLea_inlineDisclosure{appearance:none;color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border:0;align-items:center;gap:6px;margin-top:12px;padding:0;font-size:12px;display:inline-flex}._5JdLea_inlineDisclosure:hover{color:var(--dsw-alias-label-primary)}._5JdLea_modelFetchRow{align-items:center;gap:8px;display:flex}._5JdLea_modelFetch,._5JdLea_modelChoices{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);min-height:32px;color:var(--dsw-alias-label-secondary);font:inherit;border-radius:7px;font-size:12px}._5JdLea_modelFetch{cursor:pointer;padding:0 10px}._5JdLea_modelFetch:hover:not(:disabled){color:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}._5JdLea_modelFetch:disabled{opacity:.5;cursor:default}._5JdLea_modelChoices{flex:1;min-width:0;padding:0 8px}._5JdLea_modelCandidateList{flex-wrap:wrap;gap:6px 10px;margin-top:10px;display:flex}._5JdLea_modelCandidateLabel{width:100%;color:var(--dsw-alias-label-tertiary);font-size:12px}._5JdLea_modelCandidate{appearance:none;min-width:0;color:var(--dsw-alias-label-secondary);cursor:pointer;background:var(--dsw-alias-bg-layer-3);font-size:12px;line-height:1.5;font:inherit;border:1px solid #0000;border-radius:5px;align-items:center;gap:5px;padding:3px 6px;display:inline-flex}._5JdLea_modelCandidate input{margin:0}._5JdLea_modelCandidate[data-selected]{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary)}._5JdLea_footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}._5JdLea_failed{min-width:0;color:var(--dsw-alias-label-error);flex:1;margin:0;font-size:12px;line-height:1.5}._5JdLea_discard,._5JdLea_save{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}._5JdLea_discard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}._5JdLea_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}._5JdLea_save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}._5JdLea_discard:disabled,._5JdLea_save:disabled{opacity:.4;cursor:default}._5JdLea_discard:focus-visible,._5JdLea_save:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}@media (prefers-reduced-motion:reduce){._5JdLea_card,._5JdLea_chevron,._5JdLea_chevronOpen{transition:none}}._5JdLea_channelSection{padding:6px 0 2px}._5JdLea_channelEmpty{color:var(--dsw-alias-label-tertiary);margin:10px 0 0;font-size:12px;line-height:1.5}._5JdLea_channelList{flex-direction:column;gap:6px;margin:10px 0 0;padding:0;list-style:none;display:flex}._5JdLea_channelRow{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;align-items:center;gap:10px;padding:8px 10px;display:flex}._5JdLea_channelRow[data-action]{flex-wrap:wrap}._5JdLea_channelDotReady,._5JdLea_channelDotWarn{border-radius:50%;flex:none;width:9px;height:9px}._5JdLea_channelDotReady{background:var(--dsw-color-success,#2fbf71)}._5JdLea_channelDotWarn{background:var(--dsw-color-danger,#e5484d)}._5JdLea_channelMain{appearance:none;min-width:0;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;flex-direction:column;flex:1;gap:3px;padding:0;display:flex}._5JdLea_channelName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:600;line-height:1.4;overflow:hidden}._5JdLea_channelMeta{flex-wrap:wrap;align-items:center;gap:4px 8px;display:flex}._5JdLea_channelHost{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.5;font-family:var(--dsw-font-family-mono,monospace);text-overflow:ellipsis;white-space:nowrap;max-width:180px;overflow:hidden}._5JdLea_channelBadge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:0 7px;font-size:11px;font-weight:500;line-height:17px}._5JdLea_channelBadge[data-warn]{color:var(--dsw-alias-label-error)}._5JdLea_channelBadge[data-default]{background:var(--dsw-alias-bg-module-poped,var(--dsw-alias-bg-module-platform));color:var(--dsw-alias-brand-primary)}._5JdLea_channelAction{appearance:none;font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:6px;flex:none;padding:4px 8px;font-size:12px;line-height:1.5}._5JdLea_channelAction:hover:not(:disabled){color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-module-platform)}._5JdLea_channelAction[data-danger]{color:var(--dsw-alias-label-error)}._5JdLea_channelAction:disabled{opacity:.45;cursor:default}._5JdLea_channelDanger{appearance:none;border:1px solid var(--dsw-alias-label-error);color:var(--dsw-alias-label-error);font:inherit;cursor:pointer;background:0 0;border-radius:6px;flex:none;padding:3px 10px;font-size:12px}._5JdLea_channelDanger:hover:not(:disabled){background:color-mix(in srgb, var(--dsw-alias-label-error) 12%, transparent)}._5JdLea_channelDanger:disabled{opacity:.45;cursor:default}._5JdLea_deleteConfirmText{min-width:0;color:var(--dsw-alias-label-error);flex:1;font-size:12px;line-height:1.5}._5JdLea_defaultModelRow{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;align-items:center;gap:12px;margin-top:12px;padding:10px 12px;display:flex}._5JdLea_defaultModelRow label{flex:1;min-width:0}._5JdLea_defaultModelRow strong,._5JdLea_defaultModelRow small{display:block}._5JdLea_defaultModelRow strong{color:var(--dsw-alias-label-primary);font-size:12px}._5JdLea_defaultModelRow small{color:var(--dsw-alias-label-tertiary);margin-top:3px;font-size:11px;line-height:1.4}._5JdLea_defaultModelRow select{width:min(260px,48%)}._5JdLea_channelAddRow{gap:8px;margin-top:10px;display:flex}._5JdLea_channelAdd{appearance:none;border:1px dashed var(--dsw-alias-border-l2);min-height:30px;color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border-radius:8px;padding:0 12px;font-size:12px}._5JdLea_channelAdd:hover:not(:disabled){color:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}._5JdLea_channelAdd:disabled{opacity:.45;cursor:default}._5JdLea_spacer{flex:1}._5JdLea_editorBackdrop{z-index:120;background:color-mix(in srgb, var(--dsw-alias-bg-layer-1,#000) 45%, transparent);justify-content:center;align-items:flex-start;padding:9vh 16px 16px;display:flex;position:fixed;inset:0}._5JdLea_editorPanel{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:14px;width:min(560px,100%);max-height:82vh;padding:16px;overflow-y:auto;box-shadow:0 18px 50px #00000059}._5JdLea_editorHeader{border-bottom:1px solid var(--dsw-alias-border-l2);justify-content:space-between;align-items:flex-start;gap:12px;padding-bottom:10px;display:flex}._5JdLea_editorClose{appearance:none;width:26px;height:26px;color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:0;border-radius:6px;flex:none;font-size:16px;line-height:26px}._5JdLea_editorClose:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-module-platform)}._5JdLea_editorField{flex-direction:column;gap:6px;padding:12px 0 0;display:flex}._5JdLea_checkboxRow{color:var(--dsw-alias-label-secondary);cursor:pointer;align-items:center;gap:7px;font-size:12px;line-height:1.5;display:inline-flex}._5JdLea_checkboxRow input{margin:0}._5JdLea_fieldHint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:11.5px;line-height:1.5}._5JdLea_editorDivider{background:var(--dsw-alias-border-l2);height:1px;margin:14px 0 4px}._5JdLea_editorSectionHeader{justify-content:space-between;align-items:center;gap:12px;padding:10px 0 4px;display:flex}._5JdLea_editorSectionHeader ._5JdLea_label{flex:1}._5JdLea_editorTools{flex-direction:column;gap:8px;margin-top:10px;display:flex}._5JdLea_editorFooter{border-top:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding-top:12px;display:flex}._5JdLea_detectOk{color:var(--dsw-color-success,var(--dsw-alias-label-secondary));margin:0;font-size:12px;line-height:1.5}._5JdLea_modelRows{flex-direction:column;gap:8px;margin:8px 0 0;padding:0;list-style:none;display:flex}._5JdLea_modelRow{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;justify-content:space-between;align-items:center;gap:10px;padding:8px 10px;display:flex}._5JdLea_modelRowInputs{flex:1;align-items:center;gap:6px;min-width:0;display:flex}._5JdLea_modelRowInputs ._5JdLea_input{flex:1;min-width:0}._5JdLea_modelArrow{color:var(--dsw-alias-label-tertiary);flex:none;font-size:12px}._5JdLea_modelRowBadges{flex:none;align-items:center;gap:6px;display:flex}._5JdLea_modelBadge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-tertiary);border-radius:999px;padding:0 7px;font-size:11px;line-height:17px}._5JdLea_modelBadge[data-verified]{color:var(--dsw-color-success,var(--dsw-alias-label-secondary))}._5JdLea_modelBadge[data-warn]{color:var(--dsw-alias-label-error)}._5JdLea_modelRowRemove{appearance:none;width:20px;height:20px;color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:0;border-radius:4px;flex:none;padding:0;line-height:20px}._5JdLea_modelRowRemove:hover:not(:disabled){color:var(--dsw-alias-label-error);background:var(--dsw-alias-bg-module-platform)}._5JdLea_modelRowRemove:disabled{opacity:.45;cursor:default}._5JdLea_modelCandidate>._5JdLea_modelBadge{flex:none}._5JdLea_channelControls{position:relative}._5JdLea_presetInline{z-index:10;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:10px;width:min(420px,100vw - 48px);max-height:min(440px,60vh);margin:0;padding:12px;position:absolute;bottom:calc(100% + 8px);left:0;overflow-y:auto;box-shadow:0 12px 30px #0000004d}._5JdLea_presetInlineHeader{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}._5JdLea_presetList{flex-direction:column;gap:8px;margin-top:12px;display:flex}._5JdLea_presetRow{appearance:none;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);width:100%;color:inherit;font:inherit;text-align:left;cursor:pointer;border-radius:10px;flex-direction:column;align-items:flex-start;gap:3px;padding:10px 12px;display:flex}._5JdLea_presetRow:hover:not(:disabled){border-color:var(--dsw-alias-brand-primary)}._5JdLea_presetRow[data-custom]{border-style:dashed}._5JdLea_presetRow:disabled{opacity:.5;cursor:default}._5JdLea_presetName{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600;line-height:1.4}._5JdLea_presetMeta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.5;font-family:var(--dsw-font-family-mono,monospace)}._5JdLea_presetHint{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.5}._5JdLea_overview{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;margin:12px 0 14px;padding:14px}._5JdLea_overviewHead{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}._5JdLea_overviewTitle{color:var(--dsw-alias-label-primary);margin:0;font-size:14px;line-height:1.4}._5JdLea_overviewHint{color:var(--dsw-alias-label-tertiary);margin:4px 0 0;font-size:11.5px;line-height:1.5}._5JdLea_healthBadge,._5JdLea_sectionSummary{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:2px 8px;font-size:11px;line-height:17px}._5JdLea_healthBadge[data-state=ready],._5JdLea_sectionSummary[data-tone=ready]{color:var(--dsw-color-success,var(--dsw-alias-label-secondary))}._5JdLea_healthBadge[data-state=attention],._5JdLea_sectionSummary[data-tone=attention]{color:var(--dsw-alias-label-error)}._5JdLea_summaryGrid{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin-top:12px;display:grid}._5JdLea_summaryCard{appearance:none;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);min-width:0;min-height:58px;color:inherit;font:inherit;text-align:left;cursor:pointer;border-radius:10px;flex-direction:column;justify-content:center;align-items:flex-start;gap:4px;padding:9px 10px;transition:border-color .16s,background .16s;display:flex}._5JdLea_summaryCard:hover,._5JdLea_summaryCard[data-active]{border-color:var(--dsw-alias-brand-primary)}._5JdLea_summaryCard[data-tone=ready]{background:color-mix(in srgb, var(--dsw-color-success,var(--dsw-alias-brand-primary)) 7%, var(--dsw-alias-bg-layer-2))}._5JdLea_summaryCard[data-tone=attention]{background:color-mix(in srgb, var(--dsw-alias-label-error) 6%, var(--dsw-alias-bg-layer-2))}._5JdLea_summaryLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.4}._5JdLea_summaryValue{max-width:100%;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:12.5px;font-weight:600;line-height:1.4;overflow:hidden}._5JdLea_settingsSection{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;margin-top:10px;overflow:clip}._5JdLea_settingsSection[data-open]{border-color:var(--dsw-alias-label-dimmed);background:var(--dsw-alias-bg-layer-2)}._5JdLea_sectionToggle{appearance:none;width:100%;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;grid-template-columns:minmax(0,1fr) auto auto;align-items:center;gap:10px;padding:12px 13px;display:grid}._5JdLea_sectionToggle:hover{background:color-mix(in srgb, var(--dsw-alias-bg-module-platform) 45%, transparent)}._5JdLea_sectionToggle:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}._5JdLea_sectionToggleText{flex-direction:column;gap:3px;min-width:0;display:flex}._5JdLea_sectionToggleTitle{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600;line-height:1.4}._5JdLea_sectionToggleHint{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:11.5px;line-height:1.45;overflow:hidden}._5JdLea_sectionChevron{width:18px;color:var(--dsw-alias-label-tertiary);text-align:center;flex:none;font-size:12px}._5JdLea_sectionContent{border-top:1px solid var(--dsw-alias-border-l2);padding:0 13px 13px}._5JdLea_footer{z-index:4;background:color-mix(in srgb, var(--dsw-alias-bg-layer-2) 94%, transparent);backdrop-filter:blur(12px);margin:14px -16px 0;padding:12px 16px 10px;position:sticky;bottom:-8px}._5JdLea_pickerOverlay{z-index:1000;background:#0000006b;place-items:center;padding:24px;display:grid;position:fixed;inset:0}._5JdLea_pickerDialog{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:14px;flex-direction:column;width:min(540px,100vw - 32px);max-height:min(720px,84vh);padding:16px;display:flex;overflow:hidden;box-shadow:0 18px 50px #00000059}._5JdLea_pickerHeader{border-bottom:1px solid var(--dsw-alias-border-l2);justify-content:space-between;align-items:flex-start;gap:12px;padding-bottom:12px;display:flex}._5JdLea_pickerTitle{color:var(--dsw-alias-label-primary);margin:0;font-size:15px;line-height:1.4}._5JdLea_pickerHint{color:var(--dsw-alias-label-tertiary);margin:4px 0 0;font-size:12px;line-height:1.5}._5JdLea_pickerSearch{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);height:34px;color:var(--dsw-alias-label-primary);font:inherit;border-radius:8px;outline:none;flex:none;margin:12px 0 10px;padding:0 11px;font-size:13px}._5JdLea_pickerSearch:focus-visible{border-color:var(--dsw-alias-brand-primary)}._5JdLea_pickerList{flex-direction:column;gap:8px;min-height:0;padding:2px 2px 4px;display:flex;overflow-y:auto}._5JdLea_pickerList ._5JdLea_presetRow{flex:none;min-height:54px}._5JdLea_pickerEmpty{color:var(--dsw-alias-label-tertiary);text-align:center;margin:16px 0;font-size:12px;line-height:1.5}@media (width<=520px){._5JdLea_overviewHead{flex-direction:column}._5JdLea_sectionToggle{grid-template-columns:minmax(0,1fr) auto}._5JdLea_sectionToggle ._5JdLea_sectionSummary{grid-column:1/-1;justify-self:start}._5JdLea_summaryGrid{grid-template-columns:minmax(0,1fr)}}._5JdLea_subscriptionBox{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:11px;margin-top:12px;padding:12px}._5JdLea_subscriptionAccount{align-items:center;gap:9px;display:flex}._5JdLea_subscriptionAccount>div{flex-direction:column;gap:2px;min-width:0;display:flex}._5JdLea_subscriptionAccount strong{color:var(--dsw-alias-label-primary);font-size:13px;line-height:1.4}._5JdLea_subscriptionAccount small{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:11.5px;line-height:1.45;overflow:hidden}._5JdLea_subscriptionDot{background:var(--dsw-alias-label-tertiary);border-radius:50%;flex:none;width:8px;height:8px}._5JdLea_subscriptionDot[data-state=logged-in]{background:var(--dsw-color-success,#3fb950)}._5JdLea_subscriptionDot[data-state=logged-out]{background:var(--dsw-alias-label-error)}._5JdLea_subscriptionWarning{background:color-mix(in srgb, var(--dsw-alias-label-error) 7%, transparent);color:var(--dsw-alias-label-secondary);border-radius:7px;margin:9px 0 0;padding:7px 9px;font-size:11.5px;line-height:1.5}._5JdLea_pickerTabs{background:var(--dsw-alias-bg-layer-3);border-radius:9px;flex:none;grid-template-columns:repeat(2,minmax(0,1fr));gap:4px;margin-top:12px;padding:3px;display:grid}._5JdLea_pickerTabs button{appearance:none;min-height:30px;color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border:0;border-radius:7px;font-size:12px}._5JdLea_pickerTabs button[data-active]{background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);box-shadow:0 1px 2px #00000014}._5JdLea_presetAction{color:var(--dsw-alias-brand-primary);flex:none;margin-left:auto;font-size:11px;line-height:1.5}._5JdLea_subscriptionManual{border-top:1px dashed var(--dsw-alias-border-l2);margin-top:10px;padding-top:10px}";
2984
+ const css$1 = "._5JdLea_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}._5JdLea_card:hover{border-color:var(--dsw-alias-label-dimmed)}._5JdLea_card:has(._5JdLea_body){background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}._5JdLea_header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}._5JdLea_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}._5JdLea_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}._5JdLea_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}._5JdLea_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}._5JdLea_chevron,._5JdLea_chevronOpen{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}._5JdLea_chevronOpen{transform:rotate(180deg)}._5JdLea_pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}._5JdLea_body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}._5JdLea_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}._5JdLea_field+._5JdLea_field{border-top:1px solid var(--dsw-alias-border-l2)}._5JdLea_head{align-items:center;gap:8px;display:flex}._5JdLea_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}._5JdLea_badges{align-items:center;gap:8px;display:inline-flex}._5JdLea_reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}._5JdLea_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}._5JdLea_reset:disabled{cursor:default;opacity:.5}._5JdLea_hint,._5JdLea_invalid{margin:0;font-size:12px;line-height:1.5}._5JdLea_hint{color:var(--dsw-alias-label-tertiary)}._5JdLea_invalid{color:var(--dsw-alias-label-error)}._5JdLea_readOnly,._5JdLea_notExposed{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}._5JdLea_sectionTitle{color:var(--dsw-alias-label-primary);margin:0;font-size:14px;line-height:1.4}._5JdLea_sectionHint{color:var(--dsw-alias-label-tertiary);margin:-4px 0 2px;font-size:12px;line-height:1.5}._5JdLea_sectionHeader{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}._5JdLea_sectionHeader ._5JdLea_sectionHint{max-width:430px}._5JdLea_modelSummary{flex-wrap:wrap;align-items:center;gap:6px;margin-top:12px;display:flex}._5JdLea_modelChip{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);max-width:100%;color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-family-mono,monospace);border-radius:6px;align-items:center;gap:5px;padding:3px 5px 3px 8px;font-size:12px;line-height:1.5;display:inline-flex}._5JdLea_modelChip>span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}._5JdLea_modelChip button{appearance:none;width:18px;height:18px;color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:0;border-radius:4px;padding:0;line-height:18px}._5JdLea_modelChip button:hover:not(:disabled){color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-module-platform)}._5JdLea_modelChip button:disabled{cursor:default;opacity:.45}._5JdLea_manualModelRow{gap:8px;margin-top:10px;display:flex}._5JdLea_disclosure{appearance:none;border:0;border-top:1px solid var(--dsw-alias-border-l2);width:100%;color:var(--dsw-alias-label-primary);font:inherit;text-align:left;cursor:pointer;background:0 0;align-items:center;gap:8px;padding:13px 0;font-size:13px;font-weight:500;display:flex}._5JdLea_disclosure>span:nth-child(2){color:var(--dsw-alias-label-tertiary);margin-left:auto;font-size:12px;font-weight:400}._5JdLea_disclosure>span:last-child{color:var(--dsw-alias-label-tertiary)}._5JdLea_disclosure:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}._5JdLea_optionalContent{padding:0 0 8px}._5JdLea_inlineDisclosure{appearance:none;color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border:0;align-items:center;gap:6px;margin-top:12px;padding:0;font-size:12px;display:inline-flex}._5JdLea_inlineDisclosure:hover{color:var(--dsw-alias-label-primary)}._5JdLea_modelCandidateList{flex-wrap:wrap;gap:6px 10px;margin-top:10px;display:flex}._5JdLea_modelCandidateLabel{width:100%;color:var(--dsw-alias-label-tertiary);font-size:12px}._5JdLea_modelCandidate{appearance:none;min-width:0;color:var(--dsw-alias-label-secondary);cursor:pointer;background:var(--dsw-alias-bg-layer-3);font-size:12px;line-height:1.5;font:inherit;border:1px solid #0000;border-radius:5px;align-items:center;gap:5px;padding:3px 6px;display:inline-flex}._5JdLea_modelCandidate[data-selected]{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary)}._5JdLea_footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}._5JdLea_failed{min-width:0;color:var(--dsw-alias-label-error);flex:1;margin:0;font-size:12px;line-height:1.5}@media (prefers-reduced-motion:reduce){._5JdLea_card,._5JdLea_chevron,._5JdLea_chevronOpen{transition:none}}._5JdLea_channelSection,._5JdLea_schemaSection{padding:6px 0 2px}._5JdLea_schemaSection>section{background:0 0;border:0;padding:0}._5JdLea_channelEmpty{color:var(--dsw-alias-label-tertiary);margin:10px 0 0;font-size:12px;line-height:1.5}._5JdLea_channelList{flex-direction:column;gap:6px;margin:10px 0 0;padding:0;list-style:none;display:flex}._5JdLea_channelRow{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;align-items:center;gap:10px;padding:8px 10px;display:flex}._5JdLea_channelRow[data-action]{flex-wrap:wrap}._5JdLea_channelMain{appearance:none;min-width:0;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;flex-direction:column;flex:1;gap:3px;padding:0;display:flex}._5JdLea_channelName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:600;line-height:1.4;overflow:hidden}._5JdLea_channelMeta{flex-wrap:wrap;align-items:center;gap:4px 8px;display:flex}._5JdLea_deleteConfirmText{min-width:0;color:var(--dsw-alias-label-error);flex:1;font-size:12px;line-height:1.5}._5JdLea_channelAddRow{gap:8px;margin-top:10px;display:flex}._5JdLea_spacer{flex:1}._5JdLea_editorBackdrop{z-index:120;background:color-mix(in srgb, var(--dsw-alias-bg-layer-1,#000) 45%, transparent);justify-content:center;align-items:flex-start;padding:9vh 16px 16px;display:flex;position:fixed;inset:0}._5JdLea_editorPanel{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:14px;width:min(560px,100%);max-height:82vh;padding:16px;overflow-y:auto;box-shadow:0 18px 50px #00000059}._5JdLea_editorHeader{border-bottom:1px solid var(--dsw-alias-border-l2);justify-content:space-between;align-items:flex-start;gap:12px;padding-bottom:10px;display:flex}._5JdLea_editorClose{appearance:none;width:26px;height:26px;color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:0;border-radius:6px;flex:none;font-size:16px;line-height:26px}._5JdLea_editorClose:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-module-platform)}._5JdLea_editorField{flex-direction:column;gap:6px;padding:12px 0 0;display:flex}._5JdLea_editorDivider{background:var(--dsw-alias-border-l2);height:1px;margin:14px 0 4px}._5JdLea_editorSectionHeader{justify-content:space-between;align-items:center;gap:12px;padding:10px 0 4px;display:flex}._5JdLea_editorSectionHeader ._5JdLea_label{flex:1}._5JdLea_editorTools{flex-direction:column;gap:8px;margin-top:10px;display:flex}._5JdLea_editorFooter{border-top:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding-top:12px;display:flex}._5JdLea_detectOk{color:var(--dsw-color-success,var(--dsw-alias-label-secondary));margin:0;font-size:12px;line-height:1.5}._5JdLea_modelRows{flex-direction:column;gap:8px;margin:8px 0 0;padding:0;list-style:none;display:flex}._5JdLea_modelRow{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;justify-content:space-between;align-items:center;gap:10px;padding:8px 10px;display:flex}._5JdLea_modelRowInputs{flex:1;align-items:center;gap:6px;min-width:0;display:flex}._5JdLea_modelArrow{color:var(--dsw-alias-label-tertiary);flex:none;font-size:12px}._5JdLea_modelRowBadges{flex:none;align-items:center;gap:6px;display:flex}._5JdLea_modelRowRemove{appearance:none;width:20px;height:20px;color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:0;border-radius:4px;flex:none;padding:0;line-height:20px}._5JdLea_modelRowRemove:hover:not(:disabled){color:var(--dsw-alias-label-error);background:var(--dsw-alias-bg-module-platform)}._5JdLea_modelRowRemove:disabled{opacity:.45;cursor:default}._5JdLea_channelControls{position:relative}._5JdLea_presetInline{z-index:10;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:10px;width:min(420px,100vw - 48px);max-height:min(440px,60vh);margin:0;padding:12px;position:absolute;bottom:calc(100% + 8px);left:0;overflow-y:auto;box-shadow:0 12px 30px #0000004d}._5JdLea_presetInlineHeader{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}._5JdLea_presetList{flex-direction:column;gap:8px;margin-top:12px;display:flex}._5JdLea_presetRow{appearance:none;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);width:100%;color:inherit;font:inherit;text-align:left;cursor:pointer;border-radius:10px;flex-direction:column;align-items:flex-start;gap:3px;padding:10px 12px;display:flex}._5JdLea_presetRow:hover:not(:disabled){border-color:var(--dsw-alias-brand-primary)}._5JdLea_presetRow[data-custom]{border-style:dashed}._5JdLea_presetRow:disabled{opacity:.5;cursor:default}._5JdLea_presetName{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600;line-height:1.4}._5JdLea_presetMeta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.5;font-family:var(--dsw-font-family-mono,monospace)}._5JdLea_presetHint{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.5}";
3024
2985
  const tagId$1 = "@logictan/dsh-imagegen/settings-card.module.css";
3025
2986
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
3026
2987
  const tag = document.createElement("style");
@@ -3030,132 +2991,73 @@ window.__ModuleLoader__.load({
3030
2991
  document.head.appendChild(tag);
3031
2992
  }
3032
2993
  var settings_card_module_css_default = {
3033
- "textareaInvalid": "_5JdLea_textareaInvalid",
3034
- "healthBadge": "_5JdLea_healthBadge",
3035
- "pickerHeader": "_5JdLea_pickerHeader",
3036
- "overviewHint": "_5JdLea_overviewHint",
3037
- "modelChip": "_5JdLea_modelChip",
3038
- "footer": "_5JdLea_footer",
3039
- "failed": "_5JdLea_failed",
3040
- "pickerOverlay": "_5JdLea_pickerOverlay",
3041
- "subscriptionWarning": "_5JdLea_subscriptionWarning",
3042
- "sectionToggleText": "_5JdLea_sectionToggleText",
3043
- "editorSectionHeader": "_5JdLea_editorSectionHeader",
3044
- "editorBackdrop": "_5JdLea_editorBackdrop",
3045
- "editorPanel": "_5JdLea_editorPanel",
3046
2994
  "modelRowInputs": "_5JdLea_modelRowInputs",
3047
- "channelList": "_5JdLea_channelList",
3048
- "sectionDivider": "_5JdLea_sectionDivider",
3049
- "reset": "_5JdLea_reset",
3050
- "presetHint": "_5JdLea_presetHint",
2995
+ "modelRowBadges": "_5JdLea_modelRowBadges",
2996
+ "readOnly": "_5JdLea_readOnly",
2997
+ "editorClose": "_5JdLea_editorClose",
2998
+ "editorField": "_5JdLea_editorField",
2999
+ "optionalContent": "_5JdLea_optionalContent",
3051
3000
  "head": "_5JdLea_head",
3052
- "invalid": "_5JdLea_invalid",
3053
- "inlineDisclosure": "_5JdLea_inlineDisclosure",
3001
+ "presetRow": "_5JdLea_presetRow",
3002
+ "manualModelRow": "_5JdLea_manualModelRow",
3003
+ "chevron": "_5JdLea_chevron",
3004
+ "editorSectionHeader": "_5JdLea_editorSectionHeader",
3054
3005
  "badges": "_5JdLea_badges",
3055
- "versionLabel": "_5JdLea_versionLabel",
3056
- "presetAction": "_5JdLea_presetAction",
3057
- "sectionContent": "_5JdLea_sectionContent",
3058
- "notExposed": "_5JdLea_notExposed",
3059
3006
  "chevronOpen": "_5JdLea_chevronOpen",
3060
- "modelCandidateList": "_5JdLea_modelCandidateList",
3061
- "checkboxRow": "_5JdLea_checkboxRow",
3062
- "pickerDialog": "_5JdLea_pickerDialog",
3063
- "pickerHint": "_5JdLea_pickerHint",
3064
- "modelRows": "_5JdLea_modelRows",
3065
- "pickerList": "_5JdLea_pickerList",
3066
- "save": "_5JdLea_save",
3067
- "name": "_5JdLea_name",
3068
- "channelMain": "_5JdLea_channelMain",
3069
- "versionRow": "_5JdLea_versionRow",
3070
- "manualModelRow": "_5JdLea_manualModelRow",
3071
- "presetList": "_5JdLea_presetList",
3072
- "pickerEmpty": "_5JdLea_pickerEmpty",
3073
- "sectionTitle": "_5JdLea_sectionTitle",
3074
- "modelRowBadges": "_5JdLea_modelRowBadges",
3075
- "modelSection": "_5JdLea_modelSection",
3076
- "sectionHeader": "_5JdLea_sectionHeader",
3077
- "summaryCard": "_5JdLea_summaryCard",
3078
- "label": "_5JdLea_label",
3079
- "channelAdd": "_5JdLea_channelAdd",
3080
- "addModel": "_5JdLea_addModel",
3081
- "channelDotReady": "_5JdLea_channelDotReady",
3007
+ "editorDivider": "_5JdLea_editorDivider",
3082
3008
  "editorFooter": "_5JdLea_editorFooter",
3083
- "inputInvalid": "_5JdLea_inputInvalid",
3084
- "textarea": "_5JdLea_textarea",
3085
- "channelBadge": "_5JdLea_channelBadge",
3086
- "channelDotWarn": "_5JdLea_channelDotWarn",
3087
- "overviewTitle": "_5JdLea_overviewTitle",
3088
- "optionalContent": "_5JdLea_optionalContent",
3089
- "summaryValue": "_5JdLea_summaryValue",
3090
- "sectionToggleTitle": "_5JdLea_sectionToggleTitle",
3091
- "presetName": "_5JdLea_presetName",
3092
- "summaryLabel": "_5JdLea_summaryLabel",
3093
- "editorClose": "_5JdLea_editorClose",
3009
+ "detectOk": "_5JdLea_detectOk",
3010
+ "failed": "_5JdLea_failed",
3011
+ "modelArrow": "_5JdLea_modelArrow",
3012
+ "spacer": "_5JdLea_spacer",
3013
+ "modelCandidateLabel": "_5JdLea_modelCandidateLabel",
3014
+ "pending": "_5JdLea_pending",
3015
+ "channelMain": "_5JdLea_channelMain",
3094
3016
  "body": "_5JdLea_body",
3095
- "settingsSection": "_5JdLea_settingsSection",
3096
- "sectionToggle": "_5JdLea_sectionToggle",
3097
- "editorTools": "_5JdLea_editorTools",
3017
+ "description": "_5JdLea_description",
3018
+ "label": "_5JdLea_label",
3019
+ "notExposed": "_5JdLea_notExposed",
3098
3020
  "hint": "_5JdLea_hint",
3099
- "input": "_5JdLea_input",
3100
- "discard": "_5JdLea_discard",
3101
- "channelName": "_5JdLea_channelName",
3102
- "channelAddRow": "_5JdLea_channelAddRow",
3103
- "pending": "_5JdLea_pending",
3104
- "summaryGrid": "_5JdLea_summaryGrid",
3105
- "subscriptionBox": "_5JdLea_subscriptionBox",
3106
- "readOnly": "_5JdLea_readOnly",
3107
- "channelRow": "_5JdLea_channelRow",
3021
+ "modelRows": "_5JdLea_modelRows",
3022
+ "sectionHeader": "_5JdLea_sectionHeader",
3023
+ "channelControls": "_5JdLea_channelControls",
3024
+ "presetName": "_5JdLea_presetName",
3025
+ "channelSection": "_5JdLea_channelSection",
3026
+ "sectionHint": "_5JdLea_sectionHint",
3108
3027
  "presetMeta": "_5JdLea_presetMeta",
3109
- "disclosure": "_5JdLea_disclosure",
3110
- "badge": "_5JdLea_badge",
3111
- "modelFetch": "_5JdLea_modelFetch",
3112
- "modelBadge": "_5JdLea_modelBadge",
3113
- "modelArrow": "_5JdLea_modelArrow",
3114
- "channelHost": "_5JdLea_channelHost",
3115
- "modelChoices": "_5JdLea_modelChoices",
3116
- "header": "_5JdLea_header",
3117
- "sectionSummary": "_5JdLea_sectionSummary",
3118
- "presetRow": "_5JdLea_presetRow",
3119
- "headText": "_5JdLea_headText",
3120
- "versionValue": "_5JdLea_versionValue",
3121
- "subscriptionDot": "_5JdLea_subscriptionDot",
3122
- "subscriptionAccount": "_5JdLea_subscriptionAccount",
3028
+ "editorTools": "_5JdLea_editorTools",
3029
+ "modelRow": "_5JdLea_modelRow",
3030
+ "name": "_5JdLea_name",
3031
+ "modelCandidate": "_5JdLea_modelCandidate",
3032
+ "editorBackdrop": "_5JdLea_editorBackdrop",
3033
+ "inlineDisclosure": "_5JdLea_inlineDisclosure",
3034
+ "schemaSection": "_5JdLea_schemaSection",
3035
+ "card": "_5JdLea_card",
3036
+ "deleteConfirmText": "_5JdLea_deleteConfirmText",
3123
3037
  "presetInline": "_5JdLea_presetInline",
3038
+ "presetList": "_5JdLea_presetList",
3039
+ "reset": "_5JdLea_reset",
3040
+ "invalid": "_5JdLea_invalid",
3041
+ "editorPanel": "_5JdLea_editorPanel",
3042
+ "headText": "_5JdLea_headText",
3124
3043
  "channelEmpty": "_5JdLea_channelEmpty",
3125
- "modelSummary": "_5JdLea_modelSummary",
3126
- "sectionToggleHint": "_5JdLea_sectionToggleHint",
3127
- "chevron": "_5JdLea_chevron",
3128
- "modelFetchRow": "_5JdLea_modelFetchRow",
3129
- "channelSection": "_5JdLea_channelSection",
3130
- "editorDivider": "_5JdLea_editorDivider",
3131
- "overview": "_5JdLea_overview",
3132
- "pickerSearch": "_5JdLea_pickerSearch",
3133
- "select": "_5JdLea_select",
3134
- "channelControls": "_5JdLea_channelControls",
3135
- "description": "_5JdLea_description",
3044
+ "modelRowRemove": "_5JdLea_modelRowRemove",
3045
+ "presetHint": "_5JdLea_presetHint",
3136
3046
  "field": "_5JdLea_field",
3137
- "channelDanger": "_5JdLea_channelDanger",
3138
- "sectionHint": "_5JdLea_sectionHint",
3139
- "modelCandidateLabel": "_5JdLea_modelCandidateLabel",
3140
- "deleteConfirmText": "_5JdLea_deleteConfirmText",
3047
+ "disclosure": "_5JdLea_disclosure",
3141
3048
  "editorHeader": "_5JdLea_editorHeader",
3142
- "presetInlineHeader": "_5JdLea_presetInlineHeader",
3143
- "pickerTitle": "_5JdLea_pickerTitle",
3144
- "sectionChevron": "_5JdLea_sectionChevron",
3145
- "modelCandidate": "_5JdLea_modelCandidate",
3146
- "detectOk": "_5JdLea_detectOk",
3147
- "channelAction": "_5JdLea_channelAction",
3148
- "defaultModelRow": "_5JdLea_defaultModelRow",
3149
- "spacer": "_5JdLea_spacer",
3150
- "editorField": "_5JdLea_editorField",
3151
- "modelRow": "_5JdLea_modelRow",
3152
- "pickerTabs": "_5JdLea_pickerTabs",
3153
- "subscriptionManual": "_5JdLea_subscriptionManual",
3154
- "overviewHead": "_5JdLea_overviewHead",
3155
3049
  "channelMeta": "_5JdLea_channelMeta",
3156
- "fieldHint": "_5JdLea_fieldHint",
3157
- "card": "_5JdLea_card",
3158
- "modelRowRemove": "_5JdLea_modelRowRemove"
3050
+ "modelCandidateList": "_5JdLea_modelCandidateList",
3051
+ "channelRow": "_5JdLea_channelRow",
3052
+ "header": "_5JdLea_header",
3053
+ "modelChip": "_5JdLea_modelChip",
3054
+ "presetInlineHeader": "_5JdLea_presetInlineHeader",
3055
+ "sectionTitle": "_5JdLea_sectionTitle",
3056
+ "modelSummary": "_5JdLea_modelSummary",
3057
+ "footer": "_5JdLea_footer",
3058
+ "channelAddRow": "_5JdLea_channelAddRow",
3059
+ "channelList": "_5JdLea_channelList",
3060
+ "channelName": "_5JdLea_channelName"
3159
3061
  };
3160
3062
  //#endregion
3161
3063
  //#region src/client/SettingsCard.tsx
@@ -3172,6 +3074,73 @@ window.__ModuleLoader__.load({
3172
3074
  * and an editor holding API key, display name, API URL, and the model catalog
3173
3075
  * with detection.
3174
3076
  */
3077
+ /**
3078
+ * The schema mirror the shared `ConfigForm` reads its field list from.
3079
+ *
3080
+ * The host's `configForms.describe()` does not carry this namespace: the plugin
3081
+ * re-serves it over its own bridge (`/api/dsh-imagegen/settings/*`) so the key
3082
+ * writes can be diverted into the credential store. The bridge does return the
3083
+ * schema envelope, so the scope snapshot carries it and this adapter presents it
3084
+ * in the shape the form expects.
3085
+ *
3086
+ * The snapshot object is cached per schema identity. `useSyncExternalStore`
3087
+ * compares snapshots by reference, so rebuilding it on every `getSnapshot()`
3088
+ * call would re-render without end.
3089
+ */
3090
+ function createSchemaMirror(scope) {
3091
+ let cachedSchema;
3092
+ let cached = {
3093
+ status: "loading",
3094
+ view: { namespaces: [] }
3095
+ };
3096
+ return {
3097
+ getSnapshot() {
3098
+ const snapshot = scope.getSnapshot();
3099
+ const schema = snapshot.schema;
3100
+ if (schema !== cachedSchema) {
3101
+ cachedSchema = schema;
3102
+ cached = {
3103
+ status: snapshot.status,
3104
+ view: { namespaces: schema === void 0 ? [] : [{
3105
+ ns: IMAGEGEN_SETTINGS_NAMESPACE,
3106
+ schema
3107
+ }] }
3108
+ };
3109
+ }
3110
+ return cached;
3111
+ },
3112
+ subscribe(listener) {
3113
+ return scope.subscribe(listener);
3114
+ }
3115
+ };
3116
+ }
3117
+ /**
3118
+ * Present the bridge scope as the shared form's handle.
3119
+ *
3120
+ * The only difference is the value's static type: the plugin declares
3121
+ * `ImageGenConfig` (an interface, so no index signature) while the form takes a
3122
+ * plain record. They are the same object at runtime; widening here keeps the
3123
+ * plugin's own interface precise instead of adding an index signature to it.
3124
+ */
3125
+ function asConfigFormHandle(scope) {
3126
+ return {
3127
+ getSnapshot() {
3128
+ const snapshot = scope.getSnapshot();
3129
+ return {
3130
+ status: snapshot.status,
3131
+ value: snapshot.value,
3132
+ writable: snapshot.writable,
3133
+ revision: snapshot.revision
3134
+ };
3135
+ },
3136
+ subscribe(listener) {
3137
+ return scope.subscribe(listener);
3138
+ },
3139
+ mutate(ops, expectedRevision) {
3140
+ return scope.mutate(ops, expectedRevision);
3141
+ }
3142
+ };
3143
+ }
3175
3144
  /** Bridges the imagegen scope onto the card's staged forms. */
3176
3145
  var ImageGenSettingsCardController = class {
3177
3146
  scope;
@@ -3180,14 +3149,7 @@ window.__ModuleLoader__.load({
3180
3149
  /** @param scope - the bound bridge scope for the dsh-imagegen namespace. */
3181
3150
  constructor(scope) {
3182
3151
  this.scope = scope;
3183
- this.form = new CardForm(scope, [
3184
- booleanField("enabled"),
3185
- booleanField("announceToAgent"),
3186
- booleanField("allowAgentImageGeneration"),
3187
- textField("promptApiUrl"),
3188
- secretField("promptApiKey"),
3189
- textField("promptModel")
3190
- ], { secretSettled: (field) => this.scope.getSecretSetSnapshot(field) });
3152
+ this.form = new CardForm(scope, [secretField("promptApiKey")], { secretSettled: (field) => this.scope.getSecretSetSnapshot(field) });
3191
3153
  this.channelsForm = new ChannelsForm(scope);
3192
3154
  }
3193
3155
  projection() {
@@ -3216,6 +3178,8 @@ window.__ModuleLoader__.load({
3216
3178
  return {
3217
3179
  hooks: { imageGenSettingsCard: cardStore },
3218
3180
  channels: this.channelsForm.actions(),
3181
+ settingsScope: this.scope,
3182
+ schemaMirror: createSchemaMirror(this.scope),
3219
3183
  ...this.form.actions()
3220
3184
  };
3221
3185
  }
@@ -3238,6 +3202,7 @@ window.__ModuleLoader__.load({
3238
3202
  const t = tt;
3239
3203
  useImageGenLanguageTick();
3240
3204
  const state = props.useImageGenSettingsCard((snapshot) => snapshot);
3205
+ const liveModel = props.settingsScope.getSnapshot().value?.promptModel ?? "";
3241
3206
  const [open, setOpen] = (0, react.useState)(false);
3242
3207
  const [promptModels, setPromptModels] = (0, react.useState)([]);
3243
3208
  const [loadingPromptModels, setLoadingPromptModels] = (0, react.useState)(false);
@@ -3246,7 +3211,6 @@ window.__ModuleLoader__.load({
3246
3211
  const [manualPromptModel, setManualPromptModel] = (0, react.useState)("");
3247
3212
  const [enhancementOpen, setEnhancementOpen] = (0, react.useState)(false);
3248
3213
  const [promptApiOpen, setPromptApiOpen] = (0, react.useState)(false);
3249
- const [moreOpen, setMoreOpen] = (0, react.useState)(false);
3250
3214
  const [editingId, setEditingId] = (0, react.useState)(null);
3251
3215
  const [presetPickerOpen, setPresetPickerOpen] = (0, react.useState)(false);
3252
3216
  const [presets, setPresets] = (0, react.useState)([]);
@@ -3254,7 +3218,7 @@ window.__ModuleLoader__.load({
3254
3218
  const [confirmDeleteId, setConfirmDeleteId] = (0, react.useState)(null);
3255
3219
  if (!state.available) return null;
3256
3220
  const title = t("settings.title");
3257
- const blocked = !state.dirty || state.invalid || state.saving || state.channels.saving;
3221
+ !state.dirty || state.invalid || state.saving || state.channels.saving;
3258
3222
  const disabled = !state.writable;
3259
3223
  const fieldProps = {
3260
3224
  overriddenLabel: t("settings.overridden"),
@@ -3330,441 +3294,341 @@ window.__ModuleLoader__.load({
3330
3294
  }),
3331
3295
  open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3332
3296
  className: settings_card_module_css_default.body,
3333
- children: [
3334
- !state.writable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3335
- className: settings_card_module_css_default.readOnly,
3336
- role: "status",
3337
- children: t("settings.readOnly")
3338
- }) : null,
3339
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3340
- className: settings_card_module_css_default.channelSection,
3341
- "aria-label": t("channels.title"),
3297
+ children: [!state.writable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3298
+ className: settings_card_module_css_default.readOnly,
3299
+ role: "status",
3300
+ children: t("settings.readOnly")
3301
+ }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3302
+ className: settings_card_module_css_default.schemaSection,
3303
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_logictan_dsh_plugins_shared_client_client.ConfigForm, {
3304
+ namespace: IMAGEGEN_SETTINGS_NAMESPACE,
3305
+ form: asConfigFormHandle(props.settingsScope),
3306
+ describe: props.schemaMirror,
3307
+ title: t("settings.scalarsTitle"),
3342
3308
  children: [
3343
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3344
- className: settings_card_module_css_default.sectionHeader,
3345
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
3346
- className: settings_card_module_css_default.sectionTitle,
3347
- children: t("channels.title")
3348
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3349
- className: settings_card_module_css_default.sectionHint,
3350
- children: t("channels.hint")
3351
- })] })
3352
- }),
3353
- channels.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3354
- className: settings_card_module_css_default.channelEmpty,
3355
- children: t("channels.empty")
3356
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
3357
- className: settings_card_module_css_default.channelList,
3358
- children: channels.map((channel) => {
3359
- const keyHeld = state.channels.keySet[channel.id] === true;
3360
- const ready = keyHeld && channel.models.length > 0;
3361
- const isDefault = channel.id === state.channels.defaultChannelId;
3362
- if (confirmDeleteId === channel.id) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
3363
- className: settings_card_module_css_default.channelRow,
3364
- "data-action": true,
3365
- children: [
3366
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3367
- className: settings_card_module_css_default.deleteConfirmText,
3368
- children: t("channels.deleteConfirmTitle", { name: channel.name || t("channels.untitled") })
3369
- }),
3370
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3371
- type: "button",
3372
- className: settings_card_module_css_default.channelDanger,
3309
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3310
+ className: settings_card_module_css_default.channelSection,
3311
+ "aria-label": t("channels.title"),
3312
+ children: [
3313
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3314
+ className: settings_card_module_css_default.sectionHeader,
3315
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
3316
+ className: settings_card_module_css_default.sectionTitle,
3317
+ children: t("channels.title")
3318
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3319
+ className: settings_card_module_css_default.sectionHint,
3320
+ children: t("channels.hint")
3321
+ })] })
3322
+ }),
3323
+ channels.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3324
+ className: settings_card_module_css_default.channelEmpty,
3325
+ children: t("channels.empty")
3326
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
3327
+ className: settings_card_module_css_default.channelList,
3328
+ children: channels.map((channel) => {
3329
+ const keyHeld = state.channels.keySet[channel.id] === true;
3330
+ const ready = keyHeld && channel.models.length > 0;
3331
+ const isDefault = channel.id === state.channels.defaultChannelId;
3332
+ if (confirmDeleteId === channel.id) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
3333
+ className: settings_card_module_css_default.channelRow,
3334
+ "data-action": true,
3335
+ children: [
3336
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3337
+ className: settings_card_module_css_default.deleteConfirmText,
3338
+ children: t("channels.deleteConfirmTitle", { name: channel.name || t("channels.untitled") })
3339
+ }),
3340
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Button, {
3341
+ variant: "danger",
3342
+ size: "sm",
3343
+ disabled,
3344
+ onClick: () => {
3345
+ props.channels.setChannels(channels.filter((candidate) => candidate.id !== channel.id));
3346
+ if (isDefault && channels.length > 1) {
3347
+ const next = channels.find((candidate) => candidate.id !== channel.id);
3348
+ if (next !== void 0) props.channels.setDefaultChannel(next.id);
3349
+ }
3350
+ setConfirmDeleteId(null);
3351
+ if (editingId === channel.id) setEditingId(null);
3352
+ },
3353
+ children: t("channels.confirm")
3354
+ }),
3355
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Button, {
3356
+ variant: "ghost",
3357
+ size: "sm",
3358
+ disabled,
3359
+ onClick: () => {
3360
+ setConfirmDeleteId(null);
3361
+ },
3362
+ children: t("channels.cancel")
3363
+ })
3364
+ ]
3365
+ }, channel.id);
3366
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
3367
+ className: settings_card_module_css_default.channelRow,
3368
+ children: [
3369
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.StatusDot, {
3370
+ kind: ready ? "ok" : "warn",
3371
+ title: t(ready ? "channels.statusReady" : "channels.statusIncomplete")
3372
+ }),
3373
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3374
+ type: "button",
3375
+ className: settings_card_module_css_default.channelMain,
3376
+ disabled,
3377
+ onClick: () => {
3378
+ setEditingId(channel.id);
3379
+ },
3380
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3381
+ className: settings_card_module_css_default.channelName,
3382
+ children: isDefault ? `★ ${channel.name || t("channels.untitled")}` : channel.name || t("channels.untitled")
3383
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3384
+ className: settings_card_module_css_default.channelMeta,
3385
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_logictan_dsh_plugins_shared_client_client.Tag, {
3386
+ kind: !keyHeld || channel.models.length === 0 ? "warn" : "ok",
3387
+ children: [
3388
+ keyHeld ? t("channels.keySet") : t("channels.keyMissing"),
3389
+ " · ",
3390
+ channel.models.length > 0 ? t("channels.modelCount", { n: channel.models.length }) : t("channels.noModels")
3391
+ ]
3392
+ })
3393
+ })]
3394
+ }),
3395
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Button, {
3396
+ variant: "ghost",
3397
+ size: "sm",
3398
+ onClick: () => {
3399
+ setEditingId(channel.id);
3400
+ },
3401
+ children: t("channels.edit")
3402
+ }),
3403
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Button, {
3404
+ variant: "danger",
3405
+ size: "sm",
3406
+ onClick: () => {
3407
+ setConfirmDeleteId(channel.id);
3408
+ },
3409
+ children: t("channels.delete")
3410
+ })
3411
+ ]
3412
+ }, channel.id);
3413
+ })
3414
+ }),
3415
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3416
+ className: settings_card_module_css_default.channelControls,
3417
+ children: [open && presetPickerOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PresetPicker, {
3418
+ t,
3419
+ presets,
3420
+ error: presetError,
3421
+ disabled: state.writable === false,
3422
+ onLoad: () => {
3423
+ setPresetError(null);
3424
+ fetch(PRESETS_API, { method: "POST" }).then(async (response) => {
3425
+ const body = await response.json();
3426
+ if (!response.ok || body.ok !== true || body.presets === void 0) throw new Error(body.message ?? `HTTP ${response.status}`);
3427
+ setPresets(body.presets);
3428
+ }).catch((error) => {
3429
+ setPresetError(error instanceof Error ? error.message : String(error));
3430
+ });
3431
+ },
3432
+ onPick: (preset) => {
3433
+ const draft = newChannelDraft(preset);
3434
+ props.channels.setChannels([...channels, draft]);
3435
+ setPresetPickerOpen(false);
3436
+ setEditingId(draft.id);
3437
+ },
3438
+ onCustom: () => {
3439
+ const draft = newChannelDraft(void 0);
3440
+ props.channels.setChannels([...channels, draft]);
3441
+ setPresetPickerOpen(false);
3442
+ setEditingId(draft.id);
3443
+ },
3444
+ onClose: () => {
3445
+ setPresetPickerOpen(false);
3446
+ }
3447
+ }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3448
+ className: settings_card_module_css_default.channelAddRow,
3449
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_logictan_dsh_plugins_shared_client_client.Button, {
3450
+ variant: "secondary",
3451
+ size: "sm",
3373
3452
  disabled,
3374
3453
  onClick: () => {
3375
- props.channels.setChannels(channels.filter((candidate) => candidate.id !== channel.id));
3376
- if (isDefault && channels.length > 1) {
3377
- const next = channels.find((candidate) => candidate.id !== channel.id);
3378
- if (next !== void 0) props.channels.setDefaultChannel(next.id);
3379
- }
3380
- setConfirmDeleteId(null);
3381
- if (editingId === channel.id) setEditingId(null);
3454
+ setPresetError(null);
3455
+ setPresetPickerOpen(true);
3382
3456
  },
3383
- children: t("channels.confirm")
3384
- }),
3385
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3386
- type: "button",
3387
- className: settings_card_module_css_default.channelAction,
3457
+ children: ["+ ", t("channels.addProvider")]
3458
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_logictan_dsh_plugins_shared_client_client.Button, {
3459
+ variant: "secondary",
3460
+ size: "sm",
3388
3461
  disabled,
3389
3462
  onClick: () => {
3390
- setConfirmDeleteId(null);
3463
+ addCustomChannel(channels, props.channels, setEditingId);
3391
3464
  },
3392
- children: t("channels.cancel")
3393
- })
3394
- ]
3395
- }, channel.id);
3396
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
3397
- className: settings_card_module_css_default.channelRow,
3398
- children: [
3399
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3400
- className: ready ? settings_card_module_css_default.channelDotReady : settings_card_module_css_default.channelDotWarn,
3401
- "aria-hidden": "true",
3402
- title: t(ready ? "channels.statusReady" : "channels.statusIncomplete")
3403
- }),
3404
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3465
+ children: ["+ ", t("channels.addCustom")]
3466
+ })]
3467
+ })]
3468
+ })
3469
+ ]
3470
+ }),
3471
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3472
+ type: "button",
3473
+ className: settings_card_module_css_default.disclosure,
3474
+ "aria-expanded": enhancementOpen,
3475
+ onClick: () => {
3476
+ setEnhancementOpen((open) => !open);
3477
+ },
3478
+ children: [
3479
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("settings.promptEnhanceTitle") }),
3480
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("settings.optional") }),
3481
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3482
+ "aria-hidden": "true",
3483
+ children: enhancementOpen ? "⌃" : "⌄"
3484
+ })
3485
+ ]
3486
+ }),
3487
+ enhancementOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3488
+ className: settings_card_module_css_default.optionalContent,
3489
+ "aria-label": t("settings.promptEnhanceTitle"),
3490
+ children: [
3491
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3492
+ className: settings_card_module_css_default.sectionHint,
3493
+ children: t("settings.promptEnhanceHint")
3494
+ }),
3495
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3496
+ className: settings_card_module_css_default.sectionHeader,
3497
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
3498
+ className: settings_card_module_css_default.sectionTitle,
3499
+ children: t("settings.promptModel")
3500
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3501
+ className: settings_card_module_css_default.sectionHint,
3502
+ children: t("settings.promptModelDetectionHint")
3503
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Button, {
3504
+ variant: "secondary",
3505
+ size: "sm",
3506
+ loading: loadingPromptModels,
3507
+ disabled: disabled || loadingPromptModels,
3508
+ onClick: () => {
3509
+ setLoadingPromptModels(true);
3510
+ setPromptModelsError(null);
3511
+ fetch(PROMPT_ENHANCE_API.models, { method: "POST" }).then(async (response) => {
3512
+ const body = await response.json();
3513
+ if (!response.ok || body.ok !== true) throw new Error(body.message ?? `HTTP ${response.status}`);
3514
+ setPromptModels(body.models ?? []);
3515
+ }).catch((error) => {
3516
+ setPromptModelsError(error instanceof Error ? error.message : String(error));
3517
+ }).finally(() => {
3518
+ setLoadingPromptModels(false);
3519
+ });
3520
+ },
3521
+ children: loadingPromptModels ? t("settings.promptModelsLoading") : t("settings.promptModelsFetch")
3522
+ })]
3523
+ }),
3524
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3525
+ className: settings_card_module_css_default.modelSummary,
3526
+ children: [liveModel.trim() !== "" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3527
+ className: settings_card_module_css_default.modelChip,
3528
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: liveModel }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3405
3529
  type: "button",
3406
- className: settings_card_module_css_default.channelMain,
3407
3530
  disabled,
3531
+ "aria-label": `${t("settings.removeModel")}: ${liveModel}`,
3408
3532
  onClick: () => {
3409
- setEditingId(channel.id);
3410
- },
3411
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3412
- className: settings_card_module_css_default.channelName,
3413
- children: isDefault ? `★ ${channel.name || t("channels.untitled")}` : channel.name || t("channels.untitled")
3414
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3415
- className: settings_card_module_css_default.channelMeta,
3416
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3417
- className: settings_card_module_css_default.channelBadge,
3418
- "data-warn": !keyHeld || channel.models.length === 0 ? "" : void 0,
3419
- children: [
3420
- keyHeld ? t("channels.keySet") : t("channels.keyMissing"),
3421
- " · ",
3422
- channel.models.length > 0 ? t("channels.modelCount", { n: channel.models.length }) : t("channels.noModels")
3423
- ]
3424
- })
3425
- })]
3426
- }),
3427
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3428
- type: "button",
3429
- className: settings_card_module_css_default.channelAction,
3430
- onClick: () => {
3431
- setEditingId(channel.id);
3533
+ props.settingsScope.set("promptModel", "");
3432
3534
  },
3433
- children: t("channels.edit")
3434
- }),
3435
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3436
- type: "button",
3437
- className: settings_card_module_css_default.channelAction,
3438
- "data-danger": true,
3439
- onClick: () => {
3440
- setConfirmDeleteId(channel.id);
3441
- },
3442
- children: t("channels.delete")
3443
- })
3444
- ]
3445
- }, channel.id);
3446
- })
3447
- }),
3448
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3449
- className: settings_card_module_css_default.channelControls,
3450
- children: [open && presetPickerOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PresetPicker, {
3451
- t,
3452
- presets,
3453
- error: presetError,
3454
- disabled: state.writable === false,
3455
- onLoad: () => {
3456
- setPresetError(null);
3457
- fetch(PRESETS_API, { method: "POST" }).then(async (response) => {
3458
- const body = await response.json();
3459
- if (!response.ok || body.ok !== true || body.presets === void 0) throw new Error(body.message ?? `HTTP ${response.status}`);
3460
- setPresets(body.presets);
3461
- }).catch((error) => {
3462
- setPresetError(error instanceof Error ? error.message : String(error));
3463
- });
3464
- },
3465
- onPick: (preset) => {
3466
- const draft = newChannelDraft(preset);
3467
- props.channels.setChannels([...channels, draft]);
3468
- setPresetPickerOpen(false);
3469
- setEditingId(draft.id);
3470
- },
3471
- onCustom: () => {
3472
- const draft = newChannelDraft(void 0);
3473
- props.channels.setChannels([...channels, draft]);
3474
- setPresetPickerOpen(false);
3475
- setEditingId(draft.id);
3476
- },
3477
- onClose: () => {
3478
- setPresetPickerOpen(false);
3479
- }
3480
- }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3481
- className: settings_card_module_css_default.channelAddRow,
3482
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3483
- type: "button",
3484
- className: settings_card_module_css_default.channelAdd,
3485
- disabled,
3486
- onClick: () => {
3487
- setPresetError(null);
3488
- setPresetPickerOpen(true);
3489
- },
3490
- children: ["+ ", t("channels.addProvider")]
3491
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3492
- type: "button",
3493
- className: settings_card_module_css_default.channelAdd,
3494
- disabled,
3495
- onClick: () => {
3496
- addCustomChannel(channels, props.channels, setEditingId);
3497
- },
3498
- children: ["+ ", t("channels.addCustom")]
3499
- })]
3500
- })]
3501
- })
3502
- ]
3503
- }),
3504
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3505
- type: "button",
3506
- className: settings_card_module_css_default.disclosure,
3507
- "aria-expanded": enhancementOpen,
3508
- onClick: () => {
3509
- setEnhancementOpen((open) => !open);
3510
- },
3511
- children: [
3512
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("settings.promptEnhanceTitle") }),
3513
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("settings.optional") }),
3514
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3515
- "aria-hidden": "true",
3516
- children: enhancementOpen ? "⌃" : "⌄"
3517
- })
3518
- ]
3519
- }),
3520
- enhancementOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3521
- className: settings_card_module_css_default.optionalContent,
3522
- "aria-label": t("settings.promptEnhanceTitle"),
3523
- children: [
3524
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3525
- className: settings_card_module_css_default.sectionHint,
3526
- children: t("settings.promptEnhanceHint")
3527
- }),
3528
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3529
- className: settings_card_module_css_default.sectionHeader,
3530
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
3531
- className: settings_card_module_css_default.sectionTitle,
3532
- children: t("settings.promptModel")
3533
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3534
- className: settings_card_module_css_default.sectionHint,
3535
- children: t("settings.promptModelDetectionHint")
3536
- })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3537
- type: "button",
3538
- className: settings_card_module_css_default.modelFetch,
3539
- disabled: disabled || loadingPromptModels,
3540
- onClick: () => {
3541
- setLoadingPromptModels(true);
3542
- setPromptModelsError(null);
3543
- fetch(PROMPT_ENHANCE_API.models, { method: "POST" }).then(async (response) => {
3544
- const body = await response.json();
3545
- if (!response.ok || body.ok !== true) throw new Error(body.message ?? `HTTP ${response.status}`);
3546
- setPromptModels(body.models ?? []);
3547
- }).catch((error) => {
3548
- setPromptModelsError(error instanceof Error ? error.message : String(error));
3549
- }).finally(() => {
3550
- setLoadingPromptModels(false);
3551
- });
3552
- },
3553
- children: loadingPromptModels ? t("settings.promptModelsLoading") : t("settings.promptModelsFetch")
3554
- })]
3555
- }),
3556
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3557
- className: settings_card_module_css_default.modelSummary,
3558
- children: [state.promptModel.text.trim() !== "" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
3559
- className: settings_card_module_css_default.modelChip,
3560
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: state.promptModel.text }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3535
+ children: "×"
3536
+ })]
3537
+ }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Button, {
3538
+ variant: "secondary",
3539
+ size: "sm",
3540
+ disabled,
3541
+ onClick: () => {
3542
+ setManualPromptModelOpen((open) => !open);
3543
+ setEnhancementOpen(true);
3544
+ },
3545
+ children: manualPromptModelOpen ? t("settings.cancelAddModel") : t("settings.addModel")
3546
+ })]
3547
+ }),
3548
+ manualPromptModelOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3549
+ className: settings_card_module_css_default.manualModelRow,
3550
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.TextField, {
3551
+ value: manualPromptModel,
3552
+ placeholder: t("settings.addPromptModelPlaceholder"),
3553
+ disabled,
3554
+ onValueChange: setManualPromptModel
3555
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Button, {
3556
+ variant: "secondary",
3557
+ size: "sm",
3558
+ disabled: disabled || manualPromptModel.trim() === "",
3559
+ onClick: () => {
3560
+ props.settingsScope.set("promptModel", manualPromptModel);
3561
+ setManualPromptModel("");
3562
+ },
3563
+ children: t("settings.addModelConfirm")
3564
+ })]
3565
+ }) : null,
3566
+ promptModels.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3567
+ className: settings_card_module_css_default.modelCandidateList,
3568
+ role: "radiogroup",
3569
+ "aria-label": t("settings.promptModelsCandidates"),
3570
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3571
+ className: settings_card_module_css_default.modelCandidateLabel,
3572
+ children: t("settings.promptModelsCandidates")
3573
+ }), promptModels.map((candidate) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3574
+ type: "button",
3575
+ role: "radio",
3576
+ className: settings_card_module_css_default.modelCandidate,
3577
+ "aria-checked": liveModel === candidate,
3578
+ "data-selected": liveModel === candidate ? "" : void 0,
3579
+ disabled,
3580
+ onClick: () => {
3581
+ props.settingsScope.set("promptModel", candidate);
3582
+ },
3583
+ children: candidate
3584
+ }, candidate))]
3585
+ }) : null,
3586
+ promptModelsError !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3587
+ className: settings_card_module_css_default.failed,
3588
+ role: "status",
3589
+ children: promptModelsError
3590
+ }) : null,
3591
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3561
3592
  type: "button",
3562
- disabled,
3563
- "aria-label": `${t("settings.removeModel")}: ${state.promptModel.text}`,
3593
+ className: settings_card_module_css_default.inlineDisclosure,
3594
+ "aria-expanded": promptApiOpen,
3564
3595
  onClick: () => {
3565
- props.edit("promptModel", "");
3596
+ setPromptApiOpen((open) => !open);
3566
3597
  },
3567
- children: "×"
3568
- })]
3569
- }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3570
- type: "button",
3571
- className: settings_card_module_css_default.addModel,
3572
- disabled,
3573
- onClick: () => {
3574
- setManualPromptModelOpen((open) => !open);
3575
- setEnhancementOpen(true);
3576
- },
3577
- children: manualPromptModelOpen ? t("settings.cancelAddModel") : t("settings.addModel")
3578
- })]
3579
- }),
3580
- manualPromptModelOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3581
- className: settings_card_module_css_default.manualModelRow,
3582
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
3583
- className: settings_card_module_css_default.input,
3584
- value: manualPromptModel,
3585
- placeholder: t("settings.addPromptModelPlaceholder"),
3586
- disabled,
3587
- onChange: (event) => {
3588
- setManualPromptModel(event.target.value);
3589
- }
3590
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3591
- type: "button",
3592
- className: settings_card_module_css_default.addModel,
3593
- disabled: disabled || manualPromptModel.trim() === "",
3594
- onClick: () => {
3595
- props.edit("promptModel", manualPromptModel);
3596
- setManualPromptModel("");
3597
- },
3598
- children: t("settings.addModelConfirm")
3599
- })]
3600
- }) : null,
3601
- promptModels.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3602
- className: settings_card_module_css_default.modelCandidateList,
3603
- role: "radiogroup",
3604
- "aria-label": t("settings.promptModelsCandidates"),
3605
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3606
- className: settings_card_module_css_default.modelCandidateLabel,
3607
- children: t("settings.promptModelsCandidates")
3608
- }), promptModels.map((candidate) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3609
- type: "button",
3610
- role: "radio",
3611
- className: settings_card_module_css_default.modelCandidate,
3612
- "aria-checked": state.promptModel.text === candidate,
3613
- "data-selected": state.promptModel.text === candidate ? "" : void 0,
3614
- disabled,
3615
- onClick: () => {
3616
- props.edit("promptModel", candidate);
3617
- },
3618
- children: candidate
3619
- }, candidate))]
3620
- }) : null,
3621
- promptModelsError !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3622
- className: settings_card_module_css_default.failed,
3623
- role: "status",
3624
- children: promptModelsError
3598
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("settings.promptApiAdvanced") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3599
+ "aria-hidden": "true",
3600
+ children: promptApiOpen ? "⌃" : "⌄"
3601
+ })]
3602
+ }),
3603
+ promptApiOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3604
+ className: settings_card_module_css_default.optionalContent,
3605
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ValueField, {
3606
+ id: "dsh-imagegen-settings-prompt-apikey",
3607
+ label: t("settings.promptApiKey"),
3608
+ hint: t("settings.promptApiKeyHint"),
3609
+ placeholder: "sk-…",
3610
+ secret: true,
3611
+ ...fieldProps,
3612
+ ...state.promptApiKey,
3613
+ overridden: false,
3614
+ onEdit: (text) => {
3615
+ props.edit("promptApiKey", text);
3616
+ },
3617
+ onReset: () => {
3618
+ props.resetField("promptApiKey");
3619
+ }
3620
+ })
3621
+ }) : null
3622
+ ]
3625
3623
  }) : null,
3626
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3627
- type: "button",
3628
- className: settings_card_module_css_default.inlineDisclosure,
3629
- "aria-expanded": promptApiOpen,
3630
- onClick: () => {
3631
- setPromptApiOpen((open) => !open);
3632
- },
3633
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("settings.promptApiAdvanced") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3634
- "aria-hidden": "true",
3635
- children: promptApiOpen ? "⌃" : "⌄"
3636
- })]
3637
- }),
3638
- promptApiOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3639
- className: settings_card_module_css_default.optionalContent,
3640
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ValueField, {
3641
- id: "dsh-imagegen-settings-prompt-apiurl",
3642
- label: t("settings.promptApiUrl"),
3643
- hint: t("settings.promptApiUrlHint"),
3644
- placeholder: "https://api.openai.com/v1",
3645
- ...fieldProps,
3646
- ...state.promptApiUrl,
3647
- onEdit: (text) => {
3648
- props.edit("promptApiUrl", text);
3649
- },
3650
- onReset: () => {
3651
- props.resetField("promptApiUrl");
3652
- }
3653
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ValueField, {
3654
- id: "dsh-imagegen-settings-prompt-apikey",
3655
- label: t("settings.promptApiKey"),
3656
- hint: t("settings.promptApiKeyHint"),
3657
- placeholder: "sk-…",
3658
- secret: true,
3659
- ...fieldProps,
3660
- ...state.promptApiKey,
3661
- overridden: false,
3662
- onEdit: (text) => {
3663
- props.edit("promptApiKey", text);
3664
- },
3665
- onReset: () => {
3666
- props.resetField("promptApiKey");
3667
- }
3668
- })]
3669
- }) : null
3670
- ]
3671
- }) : null,
3672
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3673
- type: "button",
3674
- className: settings_card_module_css_default.disclosure,
3675
- "aria-expanded": moreOpen,
3676
- onClick: () => {
3677
- setMoreOpen((open) => !open);
3678
- },
3679
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("settings.moreOptions") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3680
- "aria-hidden": "true",
3681
- children: moreOpen ? "⌃" : "⌄"
3682
- })]
3683
- }),
3684
- moreOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3685
- className: settings_card_module_css_default.optionalContent,
3686
- children: [
3687
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BooleanField, {
3688
- id: "dsh-imagegen-settings-enabled",
3689
- label: t("settings.enabled"),
3690
- hint: t("settings.enabledHint"),
3691
- inheritLabel: t("settings.inherit"),
3692
- onLabel: t("settings.on"),
3693
- offLabel: t("settings.off"),
3694
- ...fieldProps,
3695
- ...state.enabled,
3696
- onEdit: (text) => {
3697
- props.edit("enabled", text);
3698
- },
3699
- onReset: () => {
3700
- props.resetField("enabled");
3701
- }
3702
- }),
3703
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BooleanField, {
3704
- id: "dsh-imagegen-settings-announce",
3705
- label: t("settings.announceToAgent"),
3706
- hint: t("settings.announceToAgentHint"),
3707
- inheritLabel: t("settings.inherit"),
3708
- onLabel: t("settings.on"),
3709
- offLabel: t("settings.off"),
3710
- ...fieldProps,
3711
- ...state.announceToAgent,
3712
- onEdit: (text) => {
3713
- props.edit("announceToAgent", text);
3714
- },
3715
- onReset: () => {
3716
- props.resetField("announceToAgent");
3717
- }
3718
- }),
3719
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BooleanField, {
3720
- id: "dsh-imagegen-settings-agent-generation",
3721
- label: t("settings.allowAgentImageGeneration"),
3722
- hint: t("settings.allowAgentImageGenerationHint"),
3723
- inheritLabel: t("settings.inherit"),
3724
- onLabel: t("settings.on"),
3725
- offLabel: t("settings.off"),
3726
- ...fieldProps,
3727
- ...state.allowAgentImageGeneration,
3728
- onEdit: (text) => {
3729
- props.edit("enabled", text);
3730
- },
3731
- onReset: () => {
3732
- props.resetField("enabled");
3733
- }
3734
- })
3735
- ]
3736
- }) : null,
3737
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3738
- className: settings_card_module_css_default.footer,
3739
- children: [
3740
3624
  state.failed || state.channels.failed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3741
3625
  className: settings_card_module_css_default.failed,
3742
3626
  role: "status",
3743
3627
  children: t("settings.saveFailed")
3744
- }) : null,
3745
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3746
- type: "button",
3747
- className: settings_card_module_css_default.discard,
3748
- disabled: !state.dirty || state.saving || state.channels.saving,
3749
- onClick: () => {
3750
- props.discard();
3751
- props.channels.discard();
3752
- },
3753
- children: t("settings.discard")
3754
- }),
3755
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3756
- type: "button",
3757
- className: settings_card_module_css_default.save,
3758
- disabled: blocked,
3759
- onClick: () => {
3760
- props.channels.commit();
3761
- props.save();
3762
- },
3763
- children: t(!state.saving && !state.channels.saving ? "settings.save" : "settings.saving")
3764
- })
3628
+ }) : null
3765
3629
  ]
3766
3630
  })
3767
- ]
3631
+ })]
3768
3632
  }) : null,
3769
3633
  open && editing !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChannelEditor, {
3770
3634
  t,
@@ -4000,14 +3864,13 @@ window.__ModuleLoader__.load({
4000
3864
  className: settings_card_module_css_default.label,
4001
3865
  htmlFor: "dsh-imagegen-channel-name",
4002
3866
  children: t("channels.displayName")
4003
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
3867
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.TextField, {
4004
3868
  id: "dsh-imagegen-channel-name",
4005
- className: settings_card_module_css_default.input,
4006
3869
  value: channel.name,
4007
3870
  placeholder: t("channels.untitled"),
4008
3871
  disabled: !props.writable,
4009
- onChange: (event) => {
4010
- props.onPatch({ name: event.target.value });
3872
+ onValueChange: (next) => {
3873
+ props.onPatch({ name: next });
4011
3874
  }
4012
3875
  })]
4013
3876
  }),
@@ -4017,14 +3880,13 @@ window.__ModuleLoader__.load({
4017
3880
  className: settings_card_module_css_default.label,
4018
3881
  htmlFor: "dsh-imagegen-channel-url",
4019
3882
  children: t("channels.apiUrl")
4020
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
3883
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.TextField, {
4021
3884
  id: "dsh-imagegen-channel-url",
4022
- className: settings_card_module_css_default.input,
4023
3885
  value: channel.apiUrl,
4024
3886
  placeholder: "https://api.example.com/v1",
4025
3887
  disabled: !props.writable,
4026
- onChange: (event) => {
4027
- props.onPatch({ apiUrl: event.target.value });
3888
+ onValueChange: (next) => {
3889
+ props.onPatch({ apiUrl: next });
4028
3890
  }
4029
3891
  })]
4030
3892
  }),
@@ -4046,18 +3908,17 @@ window.__ModuleLoader__.load({
4046
3908
  },
4047
3909
  children: t("channels.keyClear")
4048
3910
  }) : null]
4049
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
3911
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.SecretField, {
4050
3912
  id: "dsh-imagegen-channel-key",
4051
- className: settings_card_module_css_default.input,
4052
- type: "password",
4053
3913
  autoComplete: "off",
4054
3914
  value: keyDraft,
3915
+ configured: props.keyHeld,
4055
3916
  placeholder: props.keyHeld ? t("channels.keyReplaceHint") : t("channels.keyMissingHint"),
4056
3917
  disabled: !props.writable,
4057
- onChange: (event) => {
4058
- const value = event.target.value;
4059
- setKeyDraft(value);
4060
- props.onSetKey(value === "" ? void 0 : value);
3918
+ onValueChange: (value) => {
3919
+ const next = value;
3920
+ setKeyDraft(next);
3921
+ props.onSetKey(next === "" ? void 0 : next);
4061
3922
  }
4062
3923
  })]
4063
3924
  }),
@@ -4067,9 +3928,10 @@ window.__ModuleLoader__.load({
4067
3928
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
4068
3929
  className: settings_card_module_css_default.label,
4069
3930
  children: t("channels.modelCatalogTitle")
4070
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4071
- type: "button",
4072
- className: settings_card_module_css_default.modelFetch,
3931
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Button, {
3932
+ variant: "secondary",
3933
+ size: "sm",
3934
+ loading: detecting,
4073
3935
  disabled: !props.writable || detecting,
4074
3936
  onClick: detect,
4075
3937
  children: detecting ? t("channels.detecting") : t("channels.detect")
@@ -4097,16 +3959,15 @@ window.__ModuleLoader__.load({
4097
3959
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4098
3960
  className: settings_card_module_css_default.modelRowInputs,
4099
3961
  children: [
4100
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
4101
- className: settings_card_module_css_default.input,
3962
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.TextField, {
4102
3963
  value: model.alias,
4103
3964
  "aria-label": t("channels.modelAliasLabel"),
4104
3965
  disabled: !props.writable,
4105
- onChange: (event) => {
3966
+ onValueChange: (text) => {
4106
3967
  const next = [...channel.models];
4107
3968
  next[index] = {
4108
3969
  ...model,
4109
- alias: event.target.value
3970
+ alias: text
4110
3971
  };
4111
3972
  props.onSetModels(next);
4112
3973
  }
@@ -4115,16 +3976,15 @@ window.__ModuleLoader__.load({
4115
3976
  className: settings_card_module_css_default.modelArrow,
4116
3977
  children: "→"
4117
3978
  }),
4118
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
4119
- className: settings_card_module_css_default.input,
3979
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.TextField, {
4120
3980
  value: model.id,
4121
3981
  "aria-label": t("channels.modelIdLabel"),
4122
3982
  disabled: !props.writable,
4123
- onChange: (event) => {
3983
+ onValueChange: (text) => {
4124
3984
  const next = [...channel.models];
4125
3985
  next[index] = {
4126
3986
  ...model,
4127
- id: event.target.value
3987
+ id: text
4128
3988
  };
4129
3989
  props.onSetModels(next);
4130
3990
  }
@@ -4132,8 +3992,9 @@ window.__ModuleLoader__.load({
4132
3992
  ]
4133
3993
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4134
3994
  className: settings_card_module_css_default.modelRowBadges,
4135
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4136
- className: settings_card_module_css_default.modelBadge,
3995
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_logictan_dsh_plugins_shared_client_client.Tag, {
3996
+ mono: true,
3997
+ kind: entry.known ? "idle" : "warn",
4137
3998
  children: [entry.labelZh, entry.known ? "" : ` · ${t("channels.unknownProtocol")}`]
4138
3999
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4139
4000
  type: "button",
@@ -4153,47 +4014,41 @@ window.__ModuleLoader__.load({
4153
4014
  className: settings_card_module_css_default.editorTools,
4154
4015
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4155
4016
  className: settings_card_module_css_default.manualModelRow,
4156
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
4157
- className: settings_card_module_css_default.input,
4017
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.TextField, {
4158
4018
  value: manualId,
4159
4019
  placeholder: t("channels.manualAddPlaceholder"),
4160
4020
  disabled: !props.writable,
4161
- onChange: (event) => {
4162
- setManualId(event.target.value);
4163
- },
4021
+ onValueChange: setManualId,
4164
4022
  onKeyDown: (event) => {
4165
4023
  if (event.key === "Enter") {
4166
4024
  event.preventDefault();
4167
4025
  addManual();
4168
4026
  }
4169
4027
  }
4170
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4171
- type: "button",
4172
- className: settings_card_module_css_default.addModel,
4028
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Button, {
4029
+ variant: "secondary",
4030
+ size: "sm",
4173
4031
  disabled: !props.writable || manualId.trim() === "",
4174
4032
  onClick: addManual,
4175
4033
  children: t("channels.addModelConfirm")
4176
4034
  })]
4177
4035
  }), props.otherChannels.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4178
4036
  className: settings_card_module_css_default.manualModelRow,
4179
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
4180
- className: settings_card_module_css_default.modelChoices,
4037
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Select, {
4181
4038
  value: copyFrom,
4182
- disabled: !props.writable,
4183
- onChange: (event) => {
4184
- setCopyFrom(event.target.value);
4185
- },
4186
- "aria-label": t("channels.copyFrom"),
4187
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
4039
+ options: [{
4188
4040
  value: "",
4189
- children: t("channels.copyFrom")
4190
- }), props.otherChannels.map((other) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
4041
+ label: t("channels.copyFrom")
4042
+ }, ...props.otherChannels.map((other) => ({
4191
4043
  value: other.id,
4192
- children: other.name || t("channels.untitled")
4193
- }, other.id))]
4194
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4195
- type: "button",
4196
- className: settings_card_module_css_default.addModel,
4044
+ label: other.name || t("channels.untitled")
4045
+ }))],
4046
+ disabled: !props.writable,
4047
+ onChange: setCopyFrom,
4048
+ label: t("channels.copyFrom")
4049
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Button, {
4050
+ variant: "secondary",
4051
+ size: "sm",
4197
4052
  disabled: !props.writable || copyFrom === "",
4198
4053
  onClick: copyFromChannel,
4199
4054
  children: t("channels.copyApply")
@@ -4208,32 +4063,29 @@ window.__ModuleLoader__.load({
4208
4063
  }), candidates.map((candidate) => {
4209
4064
  const selected = channel.models.some((model) => model.alias === candidate);
4210
4065
  const entry = describeModel(candidate);
4211
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
4066
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4212
4067
  className: settings_card_module_css_default.modelCandidate,
4213
4068
  "data-selected": selected ? "" : void 0,
4214
- children: [
4215
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
4216
- type: "checkbox",
4217
- checked: selected,
4218
- disabled: !props.writable,
4219
- onChange: () => {
4220
- const merged = selected ? channel.models.filter((model) => model.alias !== candidate) : [...channel.models, {
4221
- alias: candidate,
4222
- id: candidate
4223
- }];
4224
- props.onSetModels(merged);
4225
- }
4226
- }),
4227
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: candidate }),
4228
- !entry.known ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4229
- className: settings_card_module_css_default.modelBadge,
4230
- "data-warn": true,
4231
- children: t("channels.unknownProtocol")
4232
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4233
- className: settings_card_module_css_default.modelBadge,
4234
- children: entry.labelZh
4235
- })
4236
- ]
4069
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Checkbox, {
4070
+ checked: selected,
4071
+ disabled: !props.writable,
4072
+ onCheckedChange: () => {
4073
+ const merged = selected ? channel.models.filter((model) => model.alias !== candidate) : [...channel.models, {
4074
+ alias: candidate,
4075
+ id: candidate
4076
+ }];
4077
+ props.onSetModels(merged);
4078
+ },
4079
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: candidate })
4080
+ }), !entry.known ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Tag, {
4081
+ mono: true,
4082
+ kind: "warn",
4083
+ children: t("channels.unknownProtocol")
4084
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Tag, {
4085
+ mono: true,
4086
+ kind: "idle",
4087
+ children: entry.labelZh
4088
+ })]
4237
4089
  }, candidate);
4238
4090
  })]
4239
4091
  }) : null,
@@ -4241,9 +4093,8 @@ window.__ModuleLoader__.load({
4241
4093
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4242
4094
  className: settings_card_module_css_default.editorFooter,
4243
4095
  children: [
4244
- props.isDefault ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4245
- className: settings_card_module_css_default.channelBadge,
4246
- "data-default": true,
4096
+ props.isDefault ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Tag, {
4097
+ kind: "info",
4247
4098
  children: t("channels.defaultLabel")
4248
4099
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4249
4100
  type: "button",
@@ -4253,23 +4104,22 @@ window.__ModuleLoader__.load({
4253
4104
  children: t("channels.setDefault")
4254
4105
  }),
4255
4106
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: settings_card_module_css_default.spacer }),
4256
- removeOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4257
- type: "button",
4258
- className: settings_card_module_css_default.channelDanger,
4107
+ removeOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Button, {
4108
+ variant: "danger",
4109
+ size: "sm",
4259
4110
  disabled: !props.writable,
4260
4111
  onClick: props.onRemove,
4261
4112
  children: t("channels.confirm")
4262
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4263
- type: "button",
4264
- className: settings_card_module_css_default.channelAction,
4113
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Button, {
4114
+ variant: "ghost",
4115
+ size: "sm",
4265
4116
  onClick: () => {
4266
4117
  setRemoveOpen(false);
4267
4118
  },
4268
4119
  children: t("channels.cancel")
4269
- })] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4270
- type: "button",
4271
- className: settings_card_module_css_default.channelAction,
4272
- "data-danger": true,
4120
+ })] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Button, {
4121
+ variant: "danger",
4122
+ size: "sm",
4273
4123
  onClick: () => {
4274
4124
  setRemoveOpen(true);
4275
4125
  },
@@ -4296,8 +4146,9 @@ window.__ModuleLoader__.load({
4296
4146
  }),
4297
4147
  props.overridden ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4298
4148
  className: settings_card_module_css_default.badges,
4299
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4300
- className: settings_card_module_css_default.badge,
4149
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.Tag, {
4150
+ mono: true,
4151
+ kind: "info",
4301
4152
  children: props.overriddenLabel
4302
4153
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4303
4154
  type: "button",
@@ -4316,77 +4167,26 @@ window.__ModuleLoader__.load({
4316
4167
  }) : null
4317
4168
  ]
4318
4169
  }),
4319
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
4170
+ props.secret === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.SecretField, {
4320
4171
  id: props.id,
4321
- className: props.invalid ? settings_card_module_css_default.inputInvalid : settings_card_module_css_default.input,
4322
- type: props.secret === true ? "password" : "text",
4323
- autoComplete: props.secret === true ? "off" : void 0,
4324
- ...props.invalid ? { "aria-invalid": true } : {},
4172
+ autoComplete: "off",
4325
4173
  value: props.text,
4326
4174
  placeholder: props.placeholder ?? "",
4327
4175
  disabled: props.disabled,
4328
- onChange: (event) => {
4329
- props.onEdit(event.target.value);
4330
- }
4331
- }),
4332
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4333
- className: props.invalid ? settings_card_module_css_default.invalid : settings_card_module_css_default.hint,
4334
- children: props.invalid ? props.invalidLabel : props.hint
4335
- })
4336
- ]
4337
- });
4338
- }
4339
- /** A staged boolean field: 继承 / 开 / 关. */
4340
- function BooleanField(props) {
4341
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4342
- className: settings_card_module_css_default.field,
4343
- children: [
4344
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4345
- className: settings_card_module_css_default.head,
4346
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
4347
- className: settings_card_module_css_default.label,
4348
- htmlFor: props.id,
4349
- children: props.label
4350
- }), props.overridden ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4351
- className: settings_card_module_css_default.badges,
4352
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4353
- className: settings_card_module_css_default.badge,
4354
- children: props.overriddenLabel
4355
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4356
- type: "button",
4357
- className: settings_card_module_css_default.reset,
4358
- disabled: props.disabled,
4359
- onClick: props.onReset,
4360
- children: props.resetLabel
4361
- })]
4362
- }) : null]
4363
- }),
4364
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
4176
+ invalid: props.invalid,
4177
+ configured: props.canClear,
4178
+ onValueChange: props.onEdit
4179
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_logictan_dsh_plugins_shared_client_client.TextField, {
4365
4180
  id: props.id,
4366
- className: settings_card_module_css_default.select,
4367
4181
  value: props.text,
4182
+ placeholder: props.placeholder ?? "",
4368
4183
  disabled: props.disabled,
4369
- onChange: (event) => {
4370
- props.onEdit(event.target.value);
4371
- },
4372
- children: [
4373
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
4374
- value: "",
4375
- children: props.inheritLabel
4376
- }),
4377
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
4378
- value: "true",
4379
- children: props.onLabel
4380
- }),
4381
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
4382
- value: "false",
4383
- children: props.offLabel
4384
- })
4385
- ]
4184
+ invalid: props.invalid,
4185
+ onValueChange: props.onEdit
4386
4186
  }),
4387
4187
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4388
- className: settings_card_module_css_default.hint,
4389
- children: props.hint
4188
+ className: props.invalid ? settings_card_module_css_default.invalid : settings_card_module_css_default.hint,
4189
+ children: props.invalid ? props.invalidLabel : props.hint
4390
4190
  })
4391
4191
  ]
4392
4192
  });
@@ -4395,11 +4195,11 @@ window.__ModuleLoader__.load({
4395
4195
  //#region src/client/settings-scope.ts
4396
4196
  /**
4397
4197
  * Browser-side settings scope for the dsh-imagegen namespace, served by the
4398
- * plugin's own loopback bridge routes (/api/dsh-imagegen/settings). The
4198
+ * plugin's own same-origin bridge routes (/api/dsh-imagegen/settings). The
4399
4199
  * official rc.6 settings scope answers "unavailable" for every third-party
4400
4200
  * namespace (the host-apiproxy allowlist is hard-coded), so this package
4401
- * re-serves its namespace through the host settings seam over a same-origin,
4402
- * loopback-only HTTP pair — the same pattern the dsh-web-ui family bridge
4201
+ * re-serves its namespace through the host settings seam over a same-origin
4202
+ * HTTP pair — the same pattern the dsh-web-ui family bridge
4403
4203
  * uses, self-contained per plugin.
4404
4204
  */
4405
4205
  /** Settings wire face over the bridge routes (fetch-backed). */
@@ -4456,7 +4256,8 @@ window.__ModuleLoader__.load({
4456
4256
  user: void 0,
4457
4257
  revision: void 0,
4458
4258
  writable: false,
4459
- mode: "host"
4259
+ mode: "host",
4260
+ schema: void 0
4460
4261
  });
4461
4262
  this.keySet = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)(false);
4462
4263
  this.secretSets = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)({});
@@ -4488,26 +4289,39 @@ window.__ModuleLoader__.load({
4488
4289
  return this.enqueue(() => this.read());
4489
4290
  }
4490
4291
  set(field, value) {
4491
- return this.enqueue(() => this.writeOps([{
4492
- op: "set",
4493
- path: [field],
4494
- value
4495
- }]));
4292
+ return this.enqueue(async () => {
4293
+ await this.writeOps([{
4294
+ op: "set",
4295
+ path: [field],
4296
+ value
4297
+ }]);
4298
+ });
4496
4299
  }
4497
4300
  unset(field) {
4498
- return this.enqueue(() => this.writeOps([{
4499
- op: "unset",
4500
- path: [field]
4501
- }]));
4301
+ return this.enqueue(async () => {
4302
+ await this.writeOps([{
4303
+ op: "unset",
4304
+ path: [field]
4305
+ }]);
4306
+ });
4502
4307
  }
4308
+ /**
4309
+ * Apply path ops, resolving whether the write was accepted.
4310
+ *
4311
+ * The boolean is load-bearing for the shared form: it keeps the user's draft
4312
+ * on a refusal, so a rejected edit cannot look applied. A `void` here would
4313
+ * make every refusal silently read as success.
4314
+ */
4503
4315
  mutate(ops, expectedRevision) {
4504
- return this.enqueue(() => this.writeOps([...ops], expectedRevision));
4316
+ return this.enqueueWrite(() => this.writeOps([...ops], expectedRevision));
4505
4317
  }
4506
4318
  /** Apply several path ops in one revision-fenced mutate call (atomic save).
4507
4319
  * Path ops may address plain-object fields (e.g. `channelSecrets.<id>`),
4508
4320
  * but never navigate *inside* arrays — write array fields wholesale. */
4509
4321
  mutateOps(ops) {
4510
- return this.enqueue(() => this.writeOps(ops));
4322
+ return this.enqueue(async () => {
4323
+ await this.writeOps(ops);
4324
+ });
4511
4325
  }
4512
4326
  async dispose() {
4513
4327
  this.disposed = true;
@@ -4522,6 +4336,22 @@ window.__ModuleLoader__.load({
4522
4336
  this.tail = task.catch(() => {});
4523
4337
  return task;
4524
4338
  }
4339
+ /**
4340
+ * Queue a write that reports whether it was accepted.
4341
+ *
4342
+ * Separate from `enqueue` because that one is also used for reads, whose
4343
+ * caller has nothing to decide on. Serializing through the same `tail` keeps
4344
+ * one ordering for every request on this scope.
4345
+ */
4346
+ enqueueWrite(operation) {
4347
+ if (this.disposed) return Promise.resolve(false);
4348
+ const task = this.tail.then(async () => {
4349
+ if (this.disposed) return false;
4350
+ return operation();
4351
+ });
4352
+ this.tail = task.then(() => {}, () => {});
4353
+ return task;
4354
+ }
4525
4355
  async read() {
4526
4356
  let response;
4527
4357
  try {
@@ -4562,13 +4392,14 @@ window.__ModuleLoader__.load({
4562
4392
  });
4563
4393
  } catch {
4564
4394
  await this.read();
4565
- return;
4395
+ return false;
4566
4396
  }
4567
4397
  if (!response.result.ok || this.disposed) {
4568
4398
  await this.read();
4569
- return;
4399
+ return false;
4570
4400
  }
4571
4401
  this.accept(response.result.value, void 0);
4402
+ return true;
4572
4403
  }
4573
4404
  accept(view, writable) {
4574
4405
  this.store.update((draft) => {
@@ -4578,6 +4409,7 @@ window.__ModuleLoader__.load({
4578
4409
  if (writable !== void 0) draft.writable = writable;
4579
4410
  draft.status = "ready";
4580
4411
  draft.value = view.value;
4412
+ draft.schema = view.schema;
4581
4413
  });
4582
4414
  const secretSets = Object.fromEntries((view.secrets ?? []).map((secret) => [secret.path.join("."), secret.set]));
4583
4415
  this.keySet.set(Object.values(secretSets).some(Boolean));
@@ -4587,7 +4419,7 @@ window.__ModuleLoader__.load({
4587
4419
  /**
4588
4420
  * Bind the dsh-imagegen settings scope over the bridge routes and start its
4589
4421
  * initial read (the caller mounts nothing until the scope settles).
4590
- * @param fetchFn - the fetch implementation (the global fetch on loopback).
4422
+ * @param fetchFn - the fetch implementation (the global fetch by default).
4591
4423
  * @returns the scope; unavailable when the bridge is unreachable.
4592
4424
  */
4593
4425
  function bindImageGenScope(fetchFn = fetch) {
@@ -4607,15 +4439,15 @@ window.__ModuleLoader__.load({
4607
4439
  document.head.appendChild(tag);
4608
4440
  }
4609
4441
  var image_toolview_module_css_default = {
4610
- "imageLink": "UtJPoq_imageLink",
4442
+ "image": "UtJPoq_image",
4611
4443
  "status": "UtJPoq_status",
4612
4444
  "message": "UtJPoq_message",
4613
- "error": "UtJPoq_error",
4445
+ "loading": "UtJPoq_loading",
4614
4446
  "images": "UtJPoq_images",
4447
+ "imageLink": "UtJPoq_imageLink",
4448
+ "error": "UtJPoq_error",
4615
4449
  "icon": "UtJPoq_icon",
4616
- "loading": "UtJPoq_loading",
4617
4450
  "root": "UtJPoq_root",
4618
- "image": "UtJPoq_image",
4619
4451
  "header": "UtJPoq_header"
4620
4452
  };
4621
4453
  //#endregion
@@ -4847,9 +4679,7 @@ window.__ModuleLoader__.load({
4847
4679
  return ctx.locale.subscribe(applyLocale);
4848
4680
  }, "dsh-imagegen: follow host locale");
4849
4681
  registerImageToolviews(ctx);
4850
- const scope = bindImageGenScope(ctx.get("connection")?.isLoopback === true ? (input, init) => fetch(input, init) : () => {
4851
- throw new Error("settings bridge is loopback-only");
4852
- });
4682
+ const scope = bindImageGenScope();
4853
4683
  ctx.effect(() => {
4854
4684
  const disposers = [ctx.on("connection/reset", () => {
4855
4685
  scope.load();