@mokuyoaxis/dsh-iris 0.2.7 → 0.3.0-beta.1

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.
Files changed (234) hide show
  1. package/CHANGELOG.md +143 -1
  2. package/README.en.md +109 -311
  3. package/README.md +106 -309
  4. package/bin/dsh-iris.js +452 -92
  5. package/docs/AGENT_CORE_QUICKSTART.md +64 -0
  6. package/docs/AGENT_QUICKSTART.md +2 -0
  7. package/docs/ARCHITECTURE.md +13 -3
  8. package/docs/ARTIFACT_MANIFEST.md +4 -0
  9. package/docs/AUDIO_FLOWS.md +87 -0
  10. package/docs/BETA_SCOPE.md +42 -0
  11. package/docs/CONTACT_SHEET.md +62 -0
  12. package/docs/CORE_CONNECTIONS.md +101 -0
  13. package/docs/CORE_QUICKSTART.md +110 -0
  14. package/docs/CORE_RUNTIME_CONTRACT.md +7 -2
  15. package/docs/CORE_SERVICE.md +101 -0
  16. package/docs/CORE_SKILLS.md +35 -3
  17. package/docs/DSH_COMPATIBILITY.md +21 -1
  18. package/docs/DSH_CORE_MIGRATION.md +6 -0
  19. package/docs/DSH_RC2_ADAPTATION.md +1 -1
  20. package/docs/DSH_RUNTIME.md +6 -2
  21. package/docs/HEADLESS_CLI.md +30 -5
  22. package/docs/HOST_ADAPTER_CONTRACT.md +5 -3
  23. package/docs/IMAGE_FLOW.md +4 -0
  24. package/docs/IMAGE_GENERATION.md +127 -0
  25. package/docs/LOCAL_API.md +4 -2
  26. package/docs/LOCAL_API_CONTRACT.md +42 -15
  27. package/docs/LOCAL_CREATION.md +7 -1
  28. package/docs/LOCAL_OPERATIONS.md +46 -0
  29. package/docs/LOCAL_SELECTION.md +57 -0
  30. package/docs/LOCAL_WEB.md +207 -0
  31. package/docs/MCP.md +212 -0
  32. package/docs/MEDIA_SCHEDULING.md +72 -0
  33. package/docs/MUSIC.md +2 -0
  34. package/docs/NETWORK_RESOURCES.md +106 -0
  35. package/docs/NETWORK_ROUTING.md +103 -0
  36. package/docs/NETWORK_WORKBENCH.md +65 -0
  37. package/docs/PANEL_EXTENSIONS.md +64 -0
  38. package/docs/PLUGINS.md +193 -0
  39. package/docs/PLUGIN_DEVELOPMENT.md +39 -0
  40. package/docs/PLUGIN_STARTUP.md +113 -0
  41. package/docs/PROVIDER_ADAPTER_CONTRACT.md +8 -2
  42. package/docs/PROVIDER_CREDENTIALS.md +67 -0
  43. package/docs/PROVIDER_EXTENSIONS.md +82 -0
  44. package/docs/PROVIDER_HEALTH.md +5 -1
  45. package/docs/PROVIDER_NETWORK.md +45 -0
  46. package/docs/PROVIDER_PLUGIN_CONTRACT.md +24 -0
  47. package/docs/PROVIDER_SETTINGS.md +91 -0
  48. package/docs/PROVIDER_SUBMISSION_CONTRACT.md +8 -0
  49. package/docs/ROADMAP.md +18 -8
  50. package/docs/SECURITY.md +1 -1
  51. package/docs/SYNC_DELIVERY_RECOVERY.md +5 -1
  52. package/docs/VIDEO_FLOWS.md +89 -0
  53. package/docs/VISION_CLI.md +1 -1
  54. package/docs/VISION_MODEL.md +2 -0
  55. package/docs/WEB_PROTOTYPE.md +21 -6
  56. package/docs/WEB_RECOVERY.md +46 -0
  57. package/docs/WORKBENCH_ARTIFACTS.md +6 -0
  58. package/docs/WORKBENCH_LOGIN.md +63 -0
  59. package/docs/assets/screenshots/core-connections-preview.webp +0 -0
  60. package/docs/assets/screenshots/core-model-pools-preview.webp +0 -0
  61. package/docs/assets/screenshots/core-overview-preview.webp +0 -0
  62. package/docs/assets/screenshots/core-spectrum-preview.webp +0 -0
  63. package/docs/assets/screenshots/core-studio-dark-preview.webp +0 -0
  64. package/docs/assets/screenshots/core-studio-mobile-preview.webp +0 -0
  65. package/docs/assets/screenshots/core-studio-preview.webp +0 -0
  66. package/docs/releases/0.3.0-alpha.1.md +51 -0
  67. package/docs/releases/0.3.0-beta.1.md +34 -0
  68. package/docs/screenshots.md +41 -1
  69. package/lib/actions.js +56 -4
  70. package/lib/adapters.js +75 -49
  71. package/lib/api.js +23 -13
  72. package/lib/application-runtime.js +73 -17
  73. package/lib/application-writer.js +193 -0
  74. package/lib/audio-flow-input.js +37 -0
  75. package/lib/client.d.ts +3 -3
  76. package/lib/client.js +402 -72
  77. package/lib/comfyui-adapter.js +95 -0
  78. package/lib/comfyui-client.js +60 -0
  79. package/lib/comfyui-inspection.js +73 -0
  80. package/lib/comfyui-workflow.js +94 -0
  81. package/lib/command-service.js +18 -5
  82. package/lib/config.js +49 -10
  83. package/lib/configured-image-runtime.js +69 -0
  84. package/lib/connection-skill.js +98 -0
  85. package/lib/connection-template.js +23 -0
  86. package/lib/core-artifact-store.js +84 -28
  87. package/lib/core-bridge-selection.js +31 -0
  88. package/lib/core-bridge-tools.js +85 -0
  89. package/lib/core-capability-catalog.js +192 -0
  90. package/lib/core-connection-diagnostics.js +49 -0
  91. package/lib/core-connection-store.js +277 -0
  92. package/lib/core-connections.js +225 -0
  93. package/lib/core-delivery-cache.js +8 -3
  94. package/lib/core-maintenance.js +9 -3
  95. package/lib/core-runtime.js +2 -1
  96. package/lib/core-service-client.js +174 -0
  97. package/lib/core-tasks.js +113 -21
  98. package/lib/core-writer-lease.js +16 -0
  99. package/lib/creation-request-store.js +41 -64
  100. package/lib/doctor.js +2 -2
  101. package/lib/dsh-core-adapter.js +61 -9
  102. package/lib/dsh-host-adapter.js +4 -1
  103. package/lib/dsh-provider-config.js +1 -1
  104. package/lib/dsh-service-bridge.js +67 -0
  105. package/lib/execution-ownership.js +43 -0
  106. package/lib/flow-store.js +156 -14
  107. package/lib/generation-input.js +10 -1
  108. package/lib/headless-vision.js +7 -7
  109. package/lib/image-edit-input.js +1 -1
  110. package/lib/image-flow.js +97 -31
  111. package/lib/index.js +47 -22
  112. package/lib/local-api-projection.js +15 -6
  113. package/lib/local-api-token-directory.js +31 -0
  114. package/lib/local-api.js +861 -71
  115. package/lib/local-creation.js +96 -24
  116. package/lib/local-operations.js +36 -0
  117. package/lib/local-request-root.js +86 -0
  118. package/lib/local-web-assets.js +39 -0
  119. package/lib/mcp-bridge.js +58 -0
  120. package/lib/mcp-check.js +26 -0
  121. package/lib/mcp-config.js +42 -0
  122. package/lib/mcp-delivery.js +46 -0
  123. package/lib/mcp-http.js +174 -0
  124. package/lib/mcp-server.js +69 -0
  125. package/lib/media-scheduler.js +194 -0
  126. package/lib/model-directory-service.js +37 -10
  127. package/lib/model-directory.js +3 -3
  128. package/lib/models.js +2 -2
  129. package/lib/music-transport.js +6 -3
  130. package/lib/network-config-service.js +123 -0
  131. package/lib/network-config.js +127 -0
  132. package/lib/network-doctor.js +94 -0
  133. package/lib/network-management.js +51 -0
  134. package/lib/network-policy.js +19 -0
  135. package/lib/network-route-evidence.js +38 -0
  136. package/lib/network-routing.js +283 -0
  137. package/lib/operation-runner.js +281 -0
  138. package/lib/operation-store.js +216 -0
  139. package/lib/panel-extension.js +36 -0
  140. package/lib/plugin-contract.js +194 -0
  141. package/lib/plugin-execution.js +51 -0
  142. package/lib/plugin-launch.js +86 -0
  143. package/lib/plugin-operation-store.js +101 -0
  144. package/lib/plugin-operations.js +28 -0
  145. package/lib/plugin-registry.js +109 -0
  146. package/lib/plugin-selection.js +15 -0
  147. package/lib/plugin-source-image.js +5 -0
  148. package/lib/plugin-web-assets.js +54 -0
  149. package/lib/plugins.d.ts +307 -0
  150. package/lib/plugins.js +59 -0
  151. package/lib/provider-adapter.js +7 -3
  152. package/lib/provider-adapters.js +92 -22
  153. package/lib/provider-catalog.js +64 -36
  154. package/lib/provider-config-format.js +51 -0
  155. package/lib/provider-config-service.js +143 -31
  156. package/lib/provider-context.d.ts +90 -0
  157. package/lib/provider-context.js +42 -0
  158. package/lib/provider-credentials.js +97 -0
  159. package/lib/provider-diagnostics.js +56 -0
  160. package/lib/provider-extensions.js +29 -0
  161. package/lib/provider-health.js +18 -6
  162. package/lib/provider-monitor.js +81 -0
  163. package/lib/provider-network.js +52 -0
  164. package/lib/provider-protocol.js +73 -22
  165. package/lib/provider-registry.js +128 -0
  166. package/lib/provider-response.js +38 -0
  167. package/lib/provider-settings.js +136 -0
  168. package/lib/provider-task-runner.js +132 -43
  169. package/lib/provider-transport.js +16 -0
  170. package/lib/render.js +11 -1
  171. package/lib/scheduling-policy.js +66 -0
  172. package/lib/skill-installation.js +23 -11
  173. package/lib/tasks.js +3 -2
  174. package/lib/video-flow-input.js +16 -0
  175. package/lib/video-input.js +12 -5
  176. package/lib/vision-model-routing.js +5 -0
  177. package/lib/web/app.js +703 -0
  178. package/lib/web/appearance.js +111 -0
  179. package/lib/web/comfyui.js +146 -0
  180. package/lib/web/connections.js +516 -0
  181. package/lib/web/creation.js +359 -0
  182. package/lib/web/flow-view.js +34 -0
  183. package/lib/web/gallery.js +133 -0
  184. package/lib/web/index.html +344 -0
  185. package/lib/web/media-client.js +218 -0
  186. package/lib/web/network.js +232 -0
  187. package/lib/web/plugin-panel.js +223 -0
  188. package/lib/web/plugin-status.js +140 -0
  189. package/lib/web/plugin-surface.css +17 -0
  190. package/lib/web/providers.js +513 -0
  191. package/lib/web/recovery.js +105 -0
  192. package/lib/web/startup.js +18 -0
  193. package/lib/web/styles.css +571 -0
  194. package/lib/web/transport.js +101 -0
  195. package/lib/web/workbench-login.js +165 -0
  196. package/lib/workbench-artifacts.js +3 -2
  197. package/lib/workbench-auth-cli.js +47 -0
  198. package/lib/workbench-auth.js +200 -0
  199. package/package.json +24 -6
  200. package/plugins/contact-sheet/index.d.mts +4 -0
  201. package/plugins/contact-sheet/index.mjs +33 -0
  202. package/plugins/contact-sheet/web/board.css +14 -0
  203. package/plugins/contact-sheet/web/board.mjs +93 -0
  204. package/skills/iris-core/SKILL.md +8 -4
  205. package/skills/iris-core/references/cli.md +2 -2
  206. package/skills/iris-core/references/comfyui.md +69 -0
  207. package/skills/iris-core/references/tasks.md +2 -0
  208. package/templates/plugin-starter/LICENSE +21 -0
  209. package/templates/plugin-starter/README.md +74 -0
  210. package/templates/plugin-starter/assets/peach.png +0 -0
  211. package/templates/plugin-starter/assets/violet.png +0 -0
  212. package/templates/plugin-starter/index.mjs +27 -0
  213. package/templates/plugin-starter/package.json +18 -0
  214. package/templates/plugin-starter/scripts/core-cli.mjs +20 -0
  215. package/templates/plugin-starter/scripts/environment.mjs +65 -0
  216. package/templates/plugin-starter/scripts/mcp-probe.mjs +22 -0
  217. package/templates/plugin-starter/scripts/setup.mjs +42 -0
  218. package/templates/plugin-starter/scripts/smoke.mjs +76 -0
  219. package/templates/plugin-starter/web/board.css +27 -0
  220. package/templates/plugin-starter/web/board.mjs +160 -0
  221. package/templates/plugin-starter/web/png.mjs +23 -0
  222. package/templates/provider-starter/LICENSE +21 -0
  223. package/templates/provider-starter/README.md +50 -0
  224. package/templates/provider-starter/index.d.mts +5 -0
  225. package/templates/provider-starter/index.mjs +165 -0
  226. package/templates/provider-starter/package.json +13 -0
  227. package/templates/provider-starter/scripts/core-cli.mjs +22 -0
  228. package/templates/provider-starter/scripts/environment.mjs +122 -0
  229. package/templates/provider-starter/scripts/fixture.mjs +54 -0
  230. package/templates/provider-starter/scripts/mcp-probe.mjs +21 -0
  231. package/templates/provider-starter/scripts/protocol-smoke.mjs +48 -0
  232. package/templates/provider-starter/scripts/setup.mjs +44 -0
  233. package/templates/provider-starter/scripts/smoke.mjs +145 -0
  234. package/user_guide.md +5 -1
@@ -0,0 +1,344 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN" data-auth="token" data-startup="pending">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <meta name="color-scheme" content="light dark">
7
+ <title>Iris · Core 工作台</title>
8
+ <link rel="icon" type="image/svg+xml" href="/iris-mark.svg">
9
+ <script src="/startup.js"></script>
10
+ <link rel="stylesheet" href="/styles.css">
11
+ <script type="module" src="/app.js"></script>
12
+ </head>
13
+ <body>
14
+ <div class="startup-screen" role="status" aria-live="polite">
15
+ <div class="startup-brand" aria-hidden="true">Iris<span>.</span></div>
16
+ <p class="startup-message">正在打开工作区…</p>
17
+ <div class="startup-failure"><p>工作台未能载入,请重新加载。</p><a href="/">重新加载</a></div>
18
+ <noscript><p>请启用 JavaScript 后重新加载工作台。</p></noscript>
19
+ </div>
20
+ <a class="skip-link" href="#main-content">跳到工作区</a>
21
+ <div class="app-shell">
22
+ <aside id="app-sidebar" class="app-sidebar" hidden>
23
+ <a class="brand" href="#overview" aria-label="Iris 工作台总览"><img src="/iris-mark.svg" alt="" width="32" height="32"><span>Iris<span class="brand-dot">.</span></span></a>
24
+ <p class="sidebar-label">你的工作区</p>
25
+ <nav id="workspace-nav" class="workspace-nav" aria-label="工作台" hidden>
26
+ <button id="overview-tab" class="nav-item" type="button" aria-current="false"><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="2"/><rect x="14" y="3" width="7" height="7" rx="2"/><rect x="3" y="14" width="7" height="7" rx="2"/><rect x="14" y="14" width="7" height="7" rx="2"/></svg> 总览</button>
27
+ <button id="studio-tab" class="nav-item" type="button" aria-current="page"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="m15 4 5 5M4 20l4-1L20 7a2.8 2.8 0 0 0-4-4L4 15z"/></svg> 创作</button>
28
+ <button id="media-tab" class="nav-item" type="button" aria-current="false"><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="3"/><path d="m3 16 5-5 4 4 3-3 6 6"/><circle cx="16" cy="8" r="1"/></svg> 作品</button>
29
+ <button id="connections-tab" class="nav-item" type="button" aria-current="false" hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="4" width="18" height="12" rx="2"/><path d="M8 21h8m-4-5v5m-4-13 2 2-2 2m5 0h3"/></svg> 客户端 <span id="connections-count" class="count">0</span></button>
30
+ <button id="providers-tab" class="nav-item" type="button" aria-current="false" hidden><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="4" y="3" width="16" height="7" rx="2"/><rect x="4" y="14" width="16" height="7" rx="2"/><path d="M8 6.5h.01M8 17.5h.01M12 6.5h4m-4 11h4"/></svg> 模型服务</button>
31
+ <button id="network-tab" class="nav-item" type="button" aria-current="false" hidden><svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="5" r="3"/><circle cx="5" cy="19" r="3"/><circle cx="19" cy="19" r="3"/><path d="M12 8v4M5 16v-4h14v4"/></svg> 网络出口</button>
32
+ <button id="plugins-tab" class="nav-item" type="button" aria-current="false"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 3h6v5h5v7h-5v6H9v-6H4V8h5z"/></svg> 插件</button>
33
+ <div id="plugin-navigation" class="plugin-navigation" role="group" aria-label="已启用扩展" hidden></div>
34
+ </nav>
35
+ <details id="recent-panel" class="recent-panel" open><summary><span>最近流程 <span id="history-count" class="count">0</span></span><span class="disclosure">收起</span></summary>
36
+ <p id="history-empty" class="muted" hidden>还没有流程。你的第一次创作会保存在这里。</p>
37
+ <nav id="history-list" aria-label="已保存的创作流程"></nav>
38
+ <button id="load-more" class="quiet full" type="button" hidden>加载更多</button>
39
+ </details>
40
+ <div class="sidebar-bottom"><span class="workspace-avatar" aria-hidden="true">i</span><span>本地工作区<small>作品与任务保存在 Core</small></span></div>
41
+ </aside>
42
+ <div class="main-area">
43
+ <header class="site-header">
44
+ <span class="breadcrumb">工作区 <span aria-hidden="true">/</span> <strong id="page-label">Iris Core</strong></span>
45
+ <div class="header-actions"><span id="mode-badge" class="badge">只读预览</span><button id="appearance-open" class="quiet" type="button">外观</button><button id="disconnect" class="quiet" type="button" hidden>退出登录</button></div>
46
+ </header>
47
+ <main id="main-content" tabindex="-1">
48
+ <section id="connection" class="connection card" aria-labelledby="connection-title">
49
+ <p class="eyebrow">YOUR LOCAL WORKSPACE</p>
50
+ <h1 id="connection-title">接回你的创作</h1>
51
+ <p class="intro">让想法成为作品。连接本地工作区,继续创作或接回已保存的作品。</p>
52
+ <div id="password-login" hidden>
53
+ <p id="password-hint" class="muted">正在读取工作台登录状态…</p>
54
+ <form id="password-form" autocomplete="on">
55
+ <input name="username" value="Iris" autocomplete="username" hidden>
56
+ <label for="password">访问口令</label>
57
+ <div class="password-row"><input id="password" name="password" type="password" autocomplete="current-password" minlength="8" maxlength="128" required spellcheck="false" autocapitalize="none"><button id="password-show" class="quiet" type="button" aria-pressed="false" aria-controls="password">显示</button></div>
58
+ <div id="password-confirm-row" hidden><label for="password-confirm">再次输入口令</label><input id="password-confirm" type="password" autocomplete="new-password" minlength="8" maxlength="128" spellcheck="false" autocapitalize="none"></div>
59
+ <label class="password-remember" for="password-remember"><input id="password-remember" type="checkbox" checked><span>记住此设备 <small>30 天</small></span></label>
60
+ <button id="password-submit" class="full" type="submit" disabled>进入工作台</button>
61
+ </form>
62
+ <button id="password-retry" class="quiet" type="button" hidden>重新读取登录状态</button>
63
+ <details class="password-help"><summary><span>忘记口令</span><span class="disclosure">展开</span></summary><p>可在运行 Iris 的终端重置工作台口令。重置会注销工作台登录,作品、任务和 MCP 连接会保留。</p><code>dsh-iris web password reset --data-root 你的工作区路径</code></details>
64
+ </div>
65
+ <p id="login-help" class="muted">点击启动终端给出的登录链接,即可进入。登录后刷新可继续;链接失效时,可在终端重新获取。</p>
66
+ <details id="paste-panel"><summary><span>备用登录</span><span class="disclosure">展开</span></summary>
67
+ <label class="file-button" for="token-file">选择 Token 文件<input id="token-file" type="file" aria-describedby="token-help"></label>
68
+ <p id="token-help" class="muted">使用本次启动生成的文件,或粘贴其中的 Token。退出会清除当前标签页的登录,服务重启后需要重新登录。</p>
69
+ <form id="connect-form">
70
+ <label for="token">会话 Token</label>
71
+ <div class="token-row"><input id="token" type="password" autocomplete="off" spellcheck="false" maxlength="128" placeholder="粘贴启动时生成的 Token"><button id="connect" type="submit">连接</button></div>
72
+ </form>
73
+ </details>
74
+ <p class="scope-note">连接与浏览不会提交媒体任务。创作和作品选择按服务已开启的权限提供。</p>
75
+ </section>
76
+ <p id="feedback" role="status" aria-live="polite" hidden></p>
77
+ <p id="session-notice" class="field-note" role="status" aria-live="polite" hidden></p>
78
+ <section id="overview-panel" class="overview-panel" aria-labelledby="overview-title" hidden>
79
+ <div class="overview-welcome card">
80
+ <div><p class="eyebrow">IRIS WORKSPACE</p><h1 id="overview-title">你的多模态工作区</h1><p class="muted">从一个想法开始,让作品在不同工具之间接续。</p></div>
81
+ <div class="overview-welcome-actions"><button id="overview-create" type="button">开始创作</button><button id="overview-gallery" class="secondary" type="button">浏览作品</button></div>
82
+ </div>
83
+ <dl id="overview-stats" class="overview-stats" aria-label="当前工作区"></dl>
84
+ <div class="overview-section-heading"><div><h2>创作能力</h2><p class="muted">入口、配置与实测记录分别呈现。</p></div><button id="overview-refresh" class="quiet" type="button">刷新状态</button></div>
85
+ <p id="overview-feedback" class="field-note" role="status" hidden></p>
86
+ <div id="overview-capabilities" class="overview-capabilities"></div>
87
+ <details id="overview-tools" class="overview-tools card"><summary><span>更多 Core 工具 <small>现有入口与覆盖范围</small></span><span class="disclosure">展开</span></summary><div class="overview-tool-grid">
88
+ <article><h3>裁剪与图片差异</h3><p>CLI 可裁剪图片、保存差异热力图;创作页已有图片比较,独立工具面板待接入。</p><code>run crop · media diff</code></article>
89
+ <article><h3>视频抽帧</h3><p>CLI 可提取视频帧并保存为作品,需系统 ffmpeg / ffprobe;面板与 MCP 待接入。</p><code>media frames</code></article>
90
+ <article><h3>HTML 截图</h3><p>CLI 使用显式指定的 Chromium,DSH 使用宿主浏览器;Core 面板与 MCP 待接入。</p><code>media html</code></article>
91
+ <article><h3>提示词优化与组装</h3><p>共享核心与 DSH 泡泡已有实现,需对应文本模型服务;独立 Core 面板与 MCP 待接入。</p></article>
92
+ </div></details>
93
+ <details id="overview-notes" class="overview-notes"><summary><span>这些状态如何判断</span><span class="disclosure">展开</span></summary><p>模型候选来自当前工作区配置,标注用途不等于接口可调用。历史实测仅表示记录时的结果;打开或刷新总览不会测试模型、同步远端目录或提交媒体任务。</p><p>作品页展示当前工作区的流程及其关联作品,不会自动汇入其他数据根或旧 DSH 工作区。</p></details>
94
+ </section>
95
+ <details id="recovery-panel" class="card compact-details" hidden>
96
+ <summary><span>操作核对 <small id="recovery-summary"></small></span><span class="disclosure">展开</span></summary>
97
+ <p id="recovery-note" class="muted" role="status" aria-live="polite"></p>
98
+ <ul id="recovery-list"></ul>
99
+ <button id="recovery-check" class="quiet" type="button">重新核对</button>
100
+ <button id="recovery-clear" class="quiet" type="button" hidden>处理本地标识</button>
101
+ <div id="recovery-clear-confirm" hidden><p class="field-note">清除后,本标签页将不再按这些标识核对未知操作。原流程和任务仍保留,也不会停止执行。请先核对原结果;确定清除本地标识吗?</p><button id="recovery-clear-yes" class="secondary danger" type="button">确认清除本地标识</button><button id="recovery-clear-no" class="quiet" type="button">返回</button></div>
102
+ </details>
103
+ <p id="plugin-feedback" class="field-note" role="status" aria-live="polite" hidden></p>
104
+ <section id="network-panel" hidden aria-labelledby="network-title">
105
+ <div class="page-heading management-heading"><div><p class="eyebrow">CONNECTION ROUTES</p><h1 id="network-title">网络出口</h1><p class="muted">功能选择模型,供应商连接选择出口。未绑定时继承当前环境。</p></div><div class="page-actions"><button id="network-refresh" class="quiet" type="button">重新读取</button><button id="network-new" class="secondary" type="button" hidden>+ 添加节点</button></div></div>
106
+ <p id="network-feedback" class="field-note" role="status" aria-live="polite" hidden></p>
107
+ <dl id="network-stats" class="overview-stats" aria-label="出口配置摘要"></dl>
108
+ <div id="network-leave-confirm" class="inline-confirm" hidden><p>放弃未保存编辑并离开?保存结果待核对时,请重新读取后检查。</p><div class="export-actions"><button id="network-leave-yes" class="secondary" type="button">放弃编辑并继续</button><button id="network-leave-no" class="quiet" type="button">继续编辑</button></div></div>
109
+ <nav id="network-sections" class="editor-tabs provider-sections" aria-label="网络出口分组"><button type="button" data-network-section="bindings" aria-pressed="true">供应商出口</button><button type="button" data-network-section="pools" aria-pressed="false">出口池</button><button type="button" data-network-section="nodes" aria-pressed="false">节点</button><button type="button" data-network-section="doctor" aria-pressed="false">检测</button></nav>
110
+ <div id="network-setup" class="card network-setup" hidden><h2>准备出口配置</h2><p id="network-setup-note" class="muted"></p><button id="network-init" type="button" hidden>初始化出口配置</button><details class="compact-details"><summary><span>另存启用与兼容说明</span><span class="disclosure">展开</span></summary><p>旧供应商目录与已有任务保持原样。先在终端另存启用,再用新文件正常启动 Core;页面不会替换正在运行的配置。</p><pre>dsh-iris network routing copy --network-config /private/network-v2.json --input '{"source":"/private/network-v1.json"}'
111
+ dsh-iris network catalog create --network-config /private/network-v2.json --provider-config /private/providers.json --output /private/providers-routed.json</pre><p>第一行仅用于沿用已有 v1 资源,与页面初始化二选一。已初始化 v2 时,只需第二行另存供应商目录;新目标不能覆盖已有文件。</p><p>启动时显式选择新目录和同一网络文件,并开启 --allow-network-management。普通 MCP 连接不能管理出口或读取代理认证。</p></details></div>
112
+ <div id="network-list" class="service-grid network-grid"></div>
113
+ <p id="network-empty" class="management-empty" hidden></p>
114
+ <section id="network-editor" class="card management-editor network-editor" hidden aria-labelledby="network-editor-title">
115
+ <div class="editor-heading"><button id="network-back" class="quiet back-button" type="button">← 返回列表</button><div class="section-heading"><h2 id="network-editor-title">编辑出口</h2><span id="network-editor-state" class="badge">未保存</span></div></div>
116
+ <form id="network-form"><fieldset id="network-fields">
117
+ <div id="network-node-fields" hidden><div class="provider-two-fields"><label class="field-label">稳定 ID<input id="network-node-id" maxlength="64" pattern="[A-Za-z0-9][A-Za-z0-9._-]*" autocomplete="off"></label><label class="field-label">名称<input id="network-node-label" maxlength="120" autocomplete="off"></label></div><div class="network-node-address"><label class="field-label">协议<select id="network-node-protocol"><option value="http">HTTP</option><option value="https">HTTPS</option></select></label><label class="field-label">主机<input id="network-node-host" maxlength="253" placeholder="127.0.0.1" autocomplete="off"></label><label class="field-label">端口<input id="network-node-port" type="number" min="1" max="65535" placeholder="7890"></label></div><label class="mini-check"><input id="network-node-enabled" type="checkbox" checked><span>启用节点</span></label><label class="mini-check"><input id="network-node-auth" type="checkbox"><span>使用认证环境变量</span></label><div id="network-auth-fields" class="provider-two-fields" hidden><label class="field-label">用户名变量名<input id="network-node-username" maxlength="128" placeholder="IRIS_PROXY_USERNAME" autocomplete="off"></label><label class="field-label">密码变量名<input id="network-node-password" maxlength="128" placeholder="IRIS_PROXY_PASSWORD" autocomplete="off"></label></div><p class="field-note">填写已有代理的地址,不是单独的公网 IP。认证只保存变量名,值由 Core 进程解析;不会修改 Clash 或系统路由。</p></div>
118
+ <div id="network-pool-fields" hidden><div class="provider-two-fields"><label class="field-label">稳定 ID<input id="network-pool-id" maxlength="64" pattern="[A-Za-z0-9][A-Za-z0-9._-]*" autocomplete="off"></label><label class="field-label">名称<input id="network-pool-label" maxlength="120" autocomplete="off"></label></div><label class="field-label">选择方式<select id="network-pool-mode"><option value="ordered">有序主备</option><option value="fixed">固定出口</option></select></label><label class="mini-check"><input id="network-pool-enabled" type="checkbox" checked><span>启用出口池</span></label><h3>允许的候选</h3><div id="network-candidates" class="network-candidates"></div><div class="network-candidate-add"><select id="network-candidate-choice" aria-label="添加允许的出口候选"></select><button id="network-candidate-add" class="secondary" type="button">添加候选</button></div><p class="field-note">只在业务发送前的连接预检中选择备用。固定池最多一个候选;空池可保存草稿,绑定后会阻止新请求。直连必须明确添加。</p></div>
119
+ <div id="network-binding-fields" hidden><p id="network-binding-provider" class="network-binding-name"></p><label class="field-label">此连接的出口<select id="network-binding-pool"></select></label><p id="network-binding-note" class="field-note"></p></div>
120
+ <div class="provider-footer"><button id="network-save" type="submit">保存设置</button><button id="network-cancel" class="quiet" type="button">取消更改</button><button id="network-remove" class="quiet danger" type="button" hidden>删除</button></div>
121
+ </fieldset></form>
122
+ <div id="network-delete-confirm" class="inline-confirm" hidden><p>确认删除此配置引用?仍被引用的资源会拒绝删除,作品与任务历史保留。</p><button id="network-delete-yes" class="secondary danger" type="button">确认删除</button><button id="network-delete-no" class="quiet" type="button">返回</button></div>
123
+ </section>
124
+ <section id="network-doctor" hidden aria-labelledby="network-doctor-title"><div class="card network-doctor-card"><div class="section-heading"><div><h2 id="network-doctor-title">Core 网络检测</h2><p class="field-note">状态来自运行 Core 的机器;打开、刷新此页不会发起外部请求。</p></div><span class="badge">静态检查</span></div><dl id="network-environment" class="network-facts"></dl><details class="compact-details"><summary><span>代理并存与未知状态</span><span class="disclosure">展开</span></summary><p>显式出口池只控制 Iris 自己的请求;Clash 与 Iris 同时存在不等于冲突。系统 TUN、宿主 dispatcher 和网关后半段的路线无法仅靠配置证明,保持“未知”。</p></details></div><div class="card network-probe-card"><h2>测试这条连接</h2><p class="field-note">点击后最多一次 GET、8 秒、16 KiB 响应,不跟随重定向、不携带供应商 Key,也不会生成媒体。</p><form id="network-probe-form"><div class="provider-two-fields"><label class="field-label">供应商连接<select id="network-probe-provider"></select></label><label class="field-label">测试目标<select id="network-probe-target"><option value="provider">已保存的服务地址</option><option value="ip">IP 观察 · JSON</option><option value="custom">自定义 GET</option></select></label></div><label id="network-probe-url-field" class="field-label" hidden>测试 URL<input id="network-probe-url" type="url" maxlength="2048" placeholder="https://api.ipify.org?format=json" autocomplete="off"></label><div class="provider-footer"><button id="network-probe-start" type="submit">开始检测</button><button id="network-probe-cancel" class="quiet" type="button" hidden>取消检测</button></div></form><div id="network-probe-result" class="network-probe-result" role="status" aria-live="polite" hidden></div></div></section>
125
+ <details id="network-other-bindings" class="card compact-details" hidden><summary><span>其他目录与遗留绑定</span><span class="disclosure">展开</span></summary><p class="field-note">按保存的身份展示,不扫描其他供应商文件。解除后该连接恢复继承环境。</p><div id="network-other-list"></div></details>
126
+ </section>
127
+ <section id="plugins-panel" class="plugins-panel" hidden aria-labelledby="plugins-title">
128
+ <div class="page-heading management-heading"><div><p class="eyebrow">WORKSPACE PLUGINS</p><h1 id="plugins-title">插件,让能力接续。</h1><p class="muted">查看当前加载、启用与客户端授权。</p></div><button id="plugins-refresh" class="quiet" type="button" disabled>重新读取</button></div>
129
+ <dl id="plugins-stats" class="overview-stats" aria-label="插件状态"></dl>
130
+ <p id="plugins-feedback" class="field-note" role="status" aria-live="polite" hidden></p>
131
+ <p id="plugins-authorizations-note" class="field-note" role="status" hidden></p>
132
+ <p id="plugins-updated" class="field-note" hidden></p>
133
+ <div id="plugins-list" class="plugin-status-list" aria-busy="false"></div>
134
+ <div id="plugins-empty" class="management-empty card" hidden><span class="empty-mark" aria-hidden="true">◇</span><h2>从一个插件开始</h2><p>当前服务没有加载插件。选择可信插件后,使用启动配置明确启用。</p></div>
135
+ <section id="plugins-missing-section" class="card plugin-missing-section" hidden aria-labelledby="plugins-missing-title"><h2 id="plugins-missing-title">授权引用的未加载业务</h2><p class="field-note">保留原授权和历史记录;核对准确版本后再决定是否调整。</p><ul id="plugins-missing" class="plugin-grants"></ul></section>
136
+ <div class="plugin-status-footer"><p class="field-note">加载、启用、授权分别生效。握手记录不代表持续在线,配置满足条件不等于业务实测成功。</p><button id="plugins-connections" class="secondary" type="button" hidden>管理客户端授权</button></div>
137
+ <details class="card compact-details plugin-status-help"><summary><span>如何启用与定位问题</span><span class="disclosure">展开</span></summary><p>在启动选择文件中用 entries 加载插件、operations 启用业务、panel 选择页面或预览;客户端还需单独选择业务与权限。修改后正常停止并重启 Core,当前页面不安装或热加载插件。</p><p>启动失败时服务可能尚未运行,请查看启动终端的错误码、阶段和配置字段。可先检查明确的选择文件:</p><code>dsh-iris plugins inspect --plugin-config /absolute/startup.json</code><p>inspect 会执行可信插件的加载与释放;只对确认可信的插件使用。查看状态和重新读取不会调用插件业务、探测模型或自动授权。</p></details>
138
+ </section>
139
+ <section id="plugin-page-panel" hidden aria-labelledby="plugin-page-title">
140
+ <div class="page-heading"><div><p class="eyebrow">WORKSPACE EXTENSION</p><h1 id="plugin-page-title"></h1><p id="plugin-page-identity" class="muted"></p></div></div>
141
+ <div id="plugin-page-slot" class="card plugin-slot"></div>
142
+ </section>
143
+ <section id="plugin-history-panel" hidden aria-labelledby="plugin-history-title">
144
+ <div class="page-heading"><div><p class="eyebrow">SAVED OPERATIONS</p><h1 id="plugin-history-title">业务记录</h1><p class="muted">记录与作品由 Core 保存,插件移除后仍可查看。</p></div><button id="plugin-history-refresh" class="quiet" type="button">重新读取</button></div>
145
+ <p id="plugin-history-feedback" class="field-note" role="status"></p><div id="plugin-history-list"></div>
146
+ </section>
147
+ <section id="plugin-settings-panel" hidden aria-labelledby="plugin-settings-title">
148
+ <div class="page-heading"><div><p class="eyebrow">EXTENSION SETTINGS</p><h1 id="plugin-settings-title">扩展设置</h1><p class="muted">展开需要的表单,保存前请核对修改。</p></div></div>
149
+ <div id="plugin-settings-list"></div>
150
+ </section>
151
+ <section id="gallery-panel" hidden aria-labelledby="gallery-title">
152
+ <div class="page-heading"><div><p class="eyebrow">YOUR COLLECTION</p><h1 id="gallery-title">灵感,留在这里。</h1><p class="muted">每一次选择,都可以回到原来的创作。</p></div><button id="gallery-new" class="secondary" type="button">+ 新建流程</button></div>
153
+ <div id="gallery-types" class="view-switch gallery-types" aria-label="作品类别" hidden><button type="button" data-gallery-kind="image" aria-pressed="true">图片</button><button type="button" data-gallery-kind="video" aria-pressed="false" hidden>视频</button><button type="button" data-gallery-kind="speech" aria-pressed="false">语音</button><button type="button" data-gallery-kind="transcribe" aria-pressed="false">转写</button></div>
154
+ <div class="gallery-toolbar"><div id="gallery-filters" class="view-switch" aria-label="作品筛选"><button type="button" data-filter="all" aria-pressed="true">全部 <span>0</span></button><button type="button" data-filter="selected" aria-pressed="false">已选择 <span>0</span></button><button type="button" data-filter="unselected" aria-pressed="false">未选择 <span>0</span></button></div><button id="gallery-refresh" class="quiet" type="button">刷新</button></div>
155
+ <p id="gallery-feedback" class="muted" role="status" aria-live="polite"></p>
156
+ <div id="gallery-grid" class="gallery-grid" aria-busy="false"></div>
157
+ <div id="gallery-empty" class="empty-collection" hidden><span aria-hidden="true">✧</span><h2>留一点空间给下一次灵感</h2><p class="muted">这里还没有符合筛选的流程。已有作品和选择仍保留在原工作区。</p></div>
158
+ <button id="gallery-more" class="secondary" type="button" hidden>加载更多作品</button>
159
+ </section>
160
+ <section id="connections-panel" hidden aria-label="连接中心">
161
+ <div class="page-heading management-heading"><div><h1>客户端连接</h1><p class="muted">让你的编程助手,通过 MCP 使用 Iris。</p></div><div class="page-actions"><button id="connections-refresh" class="quiet" type="button">刷新</button><button id="connection-new" class="secondary" type="button">+ 新建连接</button></div></div>
162
+ <p id="connections-feedback" role="status" aria-live="polite" hidden></p>
163
+ <div class="connections-workspace">
164
+ <div id="connections-overview"><div id="connections-list" class="service-grid"></div><div id="connections-empty" class="management-empty"><span class="empty-mark" aria-hidden="true">MCP</span><h2>连接你的第一个客户端</h2><p>自由命名,选择要开放的能力,再把配置交给客户端。</p></div>
165
+ <details id="connection-help" class="management-help"><summary><span>如何接入 MCP?</span><span class="disclosure">展开</span></summary><div class="connection-guide" aria-label="MCP 接入步骤"><ol><li><strong>1 · 创建连接</strong><span>命名并选择功能、权限</span></li><li><strong>2 · 生成配置</strong><span>选择客户端支持的接入方式</span></li><li><strong>3 · 客户端启用</strong><span>导入 MCP 配置,连接后刷新这里</span></li></ol><p id="connection-service-note" class="field-note"></p></div></details>
166
+ <details id="connection-contributions" class="management-help" hidden><summary><span>已加载的插件贡献</span><span class="disclosure">展开</span></summary><p class="field-note">加载与查看不会授予权限。以下列出声明与接入状态,客户端仍只能使用你明确选择的工具。</p><ul id="connection-contribution-list"></ul></details>
167
+ </div>
168
+ <section id="connection-editor" class="card connection-editor management-editor" hidden aria-labelledby="connection-editor-title">
169
+ <div class="editor-heading"><button id="connection-back" class="quiet back-button" type="button">← 返回列表</button><div class="section-heading"><h2 id="connection-editor-title">新建连接</h2><span id="connection-state" class="badge">尚未保存</span></div></div>
170
+ <div id="connection-leave-confirm" class="inline-confirm" hidden><p>放弃未保存的连接修改并返回列表?</p><button id="connection-leave-discard" type="button" class="secondary">放弃修改</button><button id="connection-leave-keep" type="button" class="quiet">继续编辑</button></div>
171
+ <nav class="editor-tabs connection-steps" aria-label="接入步骤"><button type="button" data-connection-view="settings" aria-pressed="true">1 · 选择与授权</button><button type="button" data-connection-view="delivery" aria-pressed="false">2 · 获取配置</button><button type="button" data-connection-view="verification" aria-pressed="false">3 · 核对接入</button><button type="button" data-connection-view="details" aria-pressed="false">详情与管理</button></nav>
172
+ <p id="connection-unsaved-note" class="field-note connection-draft-note" hidden>功能或权限有未保存的修改。请先保存,再生成配置或检查接入;客户端仍按原授权访问。</p>
173
+ <div id="connection-view-settings">
174
+ <form id="connection-form">
175
+ <fieldset id="connection-fields">
176
+ <label for="connection-name">连接名称</label><input id="connection-name" maxlength="80" required placeholder="例如:我的编程助手 · 工作项目" autocomplete="off">
177
+ <h3>媒体功能</h3><div id="connection-media" class="media-options"></div><div id="connection-image-options" class="scope-options"></div><details id="connection-future" class="tool-details"><summary><span>更多功能 <small>尚未接入</small></span><span class="disclosure">展开</span></summary><div id="connection-media-unavailable" class="media-options"></div></details>
178
+ <div id="connection-plugin-section" hidden><h3>插件业务</h3><div id="connection-plugin-options" class="scope-options"></div><p class="field-note">默认不开放。选择具体业务后,再选择允许的操作权限;安装插件不会自动授权。</p></div>
179
+ <h3>操作权限</h3><div id="connection-scopes" class="scope-options"></div><p class="field-note">只读可浏览记录;插件业务还需允许执行。绘图还需开放“导入与创建”和“执行流程”。执行可能产生供应商费用;停止只结束本地等待。</p>
180
+ <details id="connection-tool-details" class="tool-details"><summary><span>工具细选 <small id="connection-tool-count"></small></span><span class="disclosure">展开</span></summary><div id="connection-tools"></div></details>
181
+ <div class="connection-grant-review"><span class="field-note">本次授权</span><p id="connection-grant-summary"></p></div>
182
+ <div class="connection-form-actions"><button id="connection-save" type="submit">创建连接</button><span id="connection-save-note" class="muted">创建只保存配置,不调用模型。</span></div>
183
+ </fieldset>
184
+ </form>
185
+ </div>
186
+ <div id="connection-view-delivery" hidden>
187
+ <section id="connection-export" class="connection-section" hidden aria-labelledby="export-title">
188
+ <h3 id="export-title">接入配置</h3><p class="field-note">按已保存的授权生成。把配置加入客户端,重新连接后在这里刷新。</p>
189
+ <label class="template-choice" for="connection-location">Agent 是否运行在 Core 所在机器?<select id="connection-location"><option value="same">同一台机器</option><option value="other">另一台机器</option><option value="unknown">还不确定</option></select></label><p id="connection-location-note" class="field-note"></p>
190
+ <label class="template-choice" for="connection-template">接入模板<select id="connection-template"><option value="">手动选择</option></select></label>
191
+ <details class="tool-details"><summary><span>导入模板</span><span class="disclosure">展开</span></summary><p class="field-note">模板只选择传输与配置格式,不增加权限、不执行命令,也不查找或改写客户端文件。其他客户端可手动映射单条 entry。</p><div class="export-actions"><button id="connection-template-example" class="quiet" type="button">下载示例</button><button id="connection-template-import" class="quiet" type="button">导入 JSON</button><input id="connection-template-file" type="file" accept="application/json,.json" hidden></div></details>
192
+ <p id="connection-template-note" class="field-note" hidden></p>
193
+ <div class="export-options"><label>传输<select id="connection-transport"><option value="stdio">stdio · 本机</option><option value="http">HTTP · 本机</option></select></label><label>格式<select id="connection-format"><option value="mcpServers">mcpServers</option><option value="entry">单条 entry</option><option value="claude-json">Claude Code · JSON</option><option value="codex-toml">Codex · TOML</option></select></label><button id="connection-export-button" class="secondary" type="button">生成配置</button></div>
194
+ <p id="connection-transport-note" class="field-note"></p>
195
+ <p class="field-note">按所选客户端合并 JSON 或 TOML,保留已有配置,然后在客户端启用。其他客户端也可手动填写单条 entry。</p>
196
+ <div id="connection-export-result" hidden><p id="connection-export-note" class="field-note"></p><textarea id="connection-configuration" readonly spellcheck="false" rows="7" aria-label="MCP 接入配置"></textarea><div class="export-actions"><button id="connection-copy" class="quiet" type="button">复制</button><button id="connection-download" class="quiet" type="button">下载 JSON</button><button id="connection-clear-export" class="quiet" type="button">隐藏配置</button></div></div>
197
+ <div class="connection-next"><button id="connection-verify-next" class="secondary" type="button">下一步:核对接入 →</button><p class="field-note">将配置合并到客户端后,启动或重新连接 MCP;不覆盖已有配置。</p></div>
198
+ <details id="connection-skill-details" class="tool-details"><summary><span>连接专属 Skill</span><span class="disclosure">展开</span></summary><p class="field-note">英文说明附中文标题,仅包含当前有效工具。下载文件不含密钥;权限改变后请重新生成并安装。</p><button id="connection-skill-generate" class="secondary" type="button">生成说明</button><div id="connection-skill-result" hidden><textarea id="connection-skill-preview" readonly spellcheck="false" rows="8" aria-label="Skill 说明预览"></textarea><p class="field-note">下载后,在本机明确指定客户端的 Skills 目录安装:</p><code class="skill-install-command">dsh-iris skills install --bundle /absolute/path/iris-skill.json --directory /absolute/path/skills</code><div class="export-actions"><button id="connection-skill-download" class="quiet" type="button">下载 Skill 文件</button><button id="connection-skill-clear" class="quiet" type="button">隐藏说明</button></div></div></details>
199
+ </section>
200
+ </div>
201
+ <div id="connection-view-verification" hidden>
202
+ <div class="connection-verification-heading"><h3>接入核对</h3><p class="field-note">配置、Iris 端检查和客户端握手分别确认。这里不会安装客户端或提交媒体任务。</p></div>
203
+ <ol class="connection-evidence">
204
+ <li><span class="connection-evidence-number" aria-hidden="true">1</span><div><h3 id="connection-export-state">本页未记录当前配置导出</h3><p id="connection-export-evidence" class="field-note"></p></div></li>
205
+ <li><span class="connection-evidence-number" aria-hidden="true">2</span><div><h3 id="connection-check-state">尚未检查当前配置</h3><p id="connection-check-evidence" class="field-note"></p><ul id="connection-check-issues" class="connection-check-issues"></ul><details id="connection-check-tool-details" class="tool-details"><summary><span>当前允许的工具</span><span class="disclosure">展开</span></summary><p id="connection-check-tools-note" class="field-note"></p><ul id="connection-check-tools" class="connection-check-tools"></ul></details></div></li>
206
+ <li><span class="connection-evidence-number" aria-hidden="true">3</span><div><h3 id="connection-client-state">等待客户端握手与声明</h3><ul id="connection-client-evidence" class="connection-client-evidence"></ul><p class="field-note">名称/版本属于可选声明,未收到不等于调用失败。仅桥接或 CLI 自检握手不作为 Agent 启用证据;握手不代表持续在线、工具已被发现或媒体实测。</p></div></li>
207
+ </ol>
208
+ <div class="export-actions"><button id="connection-check" class="secondary" type="button">检查 Iris 端与接入记录</button><button id="connection-return-settings" class="quiet" type="button">返回功能与权限</button></div>
209
+ <details class="tool-details"><summary><span>客户端还没有出现?</span><span class="disclosure">展开</span></summary><p class="field-note">确认 Core 仍在运行,Agent 与 Core 的部署位置正确,配置已合并并在客户端启用。客户端可在已允许工具中发起一次只读调用;没有对应工具时不要擅自扩大权限。stdio 需重启桥进程加载新工具表。</p><p class="field-note">若需要从客户端所在机器验证配置、传输与临时握手,可使用既有命令:</p><code class="skill-install-command">dsh-iris mcp check --connection-file /absolute/client.json</code><p class="field-note">使用真正的 MCP client.json;这不是工作台登录 Token 或 server-grants.json。自检通过仍不代表 Agent 已启用 MCP。</p></details>
210
+ </div>
211
+ <div id="connection-view-details" hidden><dl id="connection-facts" hidden></dl>
212
+ <section id="connection-revoke-section" class="connection-section" hidden>
213
+ <div class="export-actions"><button id="connection-revoke" class="quiet danger" type="button">撤销连接</button><button id="connection-delete" class="quiet danger" type="button">删除连接</button></div>
214
+ <div id="connection-revoke-confirm" hidden><p>撤销后,已导出的配置立即失效。已接收的操作继续保留;不会取消供应商任务或保证停止计费。</p><div class="export-actions"><button id="connection-revoke-yes" class="secondary danger" type="button">确认撤销</button><button id="connection-revoke-no" class="quiet" type="button">返回</button></div></div>
215
+ <div id="connection-delete-confirm" hidden><p>删除后,连接将从列表移除,旧配置失效。作品、任务和已接收的操作保留;不会取消供应商任务。Iris 保留私有撤销档案,不会修改客户端的 MCP 配置。</p><div class="export-actions"><button id="connection-delete-yes" class="secondary danger" type="button">确认删除</button><button id="connection-delete-no" class="quiet" type="button">返回</button></div></div>
216
+ </section>
217
+ </div>
218
+ </section>
219
+ </div>
220
+ </section>
221
+ <section id="providers-panel" hidden aria-labelledby="providers-title">
222
+ <div class="page-heading management-heading"><div><h1 id="providers-title">模型服务 <span id="providers-count" class="count">0</span></h1><p class="muted">连接 API 或 ComfyUI,为创作准备好模型。</p></div><div class="page-actions"><button id="providers-refresh" class="quiet" type="button">重新读取</button><button id="provider-new" class="secondary" type="button">+ 添加服务</button></div></div>
223
+ <p id="providers-feedback" role="status" aria-live="polite" hidden></p>
224
+ <nav id="provider-sections" class="editor-tabs provider-sections" aria-label="模型服务分组"><button type="button" data-provider-section="suppliers" aria-pressed="true">供应商</button><button type="button" data-provider-section="pools" aria-pressed="false">功能模型池</button><button type="button" data-provider-section="health" aria-pressed="false">健康检测</button></nav>
225
+ <div id="provider-close-confirm" class="inline-confirm" hidden><p>放弃未保存修改并离开?</p><div class="export-actions"><button id="provider-close-discard" class="secondary" type="button">放弃修改</button><button id="provider-close-cancel" class="quiet" type="button">继续编辑</button></div></div>
226
+ <div id="providers-reload-confirm" class="card reload-confirm" hidden><p>重新读取将放弃当前未保存编辑,并载入文件中的最新设置。</p><button id="providers-reload-yes" class="secondary" type="button">确认重新读取</button><button id="providers-reload-no" class="quiet" type="button">保留草稿</button></div>
227
+ <section id="provider-pool-panel" class="card provider-pool-panel" hidden aria-label="功能模型池"><p class="field-note">自动按已确认用途选择;手动按优先顺序;停用停止新调用。池变化只影响新请求。</p><form id="provider-pool-form"><fieldset id="provider-pool-fields"><div id="provider-assignments"></div><div class="provider-footer"><button id="provider-pool-save" type="submit">保存模型池</button><button id="provider-pool-cancel" class="quiet" type="button">取消更改</button><p id="provider-pool-note" class="field-note"></p></div></fieldset></form></section>
228
+ <section id="provider-health-panel" hidden aria-label="能力健康与连接检查"><div class="section-heading"><h2>能力光谱</h2><button id="provider-health-refresh" class="quiet" type="button">刷新状态</button></div><p class="field-note">候选、近期成功与当前受阻分别呈现。刷新只读本地记录。</p><div id="provider-spectrum" class="provider-spectrum"></div><details id="provider-health-details" class="card provider-health-details"><summary><span id="provider-health-title">能力详情</span><span class="disclosure">展开</span></summary><div id="provider-health-models"></div></details><h2 class="provider-check-heading">连接检查与保活</h2><p class="field-note">只读取目录或 ComfyUI 服务状态,不生成媒体;连接可达不等于模型可用。保活默认关闭,仅本次 Core 服务生效。</p><div id="provider-monitors" class="service-grid"></div></section>
229
+ <div class="providers-workspace">
230
+ <div id="providers-overview"><div id="providers-list" class="service-grid"></div><div id="providers-empty" class="management-empty"><span class="empty-mark" aria-hidden="true">API</span><h2>从一个模型服务开始</h2><p>使用自己的 API,或连接已经运行的 ComfyUI。</p></div></div>
231
+ <section id="provider-editor" class="card provider-editor management-editor" hidden aria-labelledby="provider-editor-title">
232
+ <div class="editor-heading"><button id="provider-back" class="quiet back-button" type="button">← 返回列表</button><div class="section-heading"><div class="provider-heading"><h2 id="provider-editor-title">添加供应商</h2><span id="provider-comfy-mode" class="provider-mode-pill" hidden><span aria-hidden="true">✦</span> ComfyUI Studio</span></div><span id="provider-state" class="badge">未保存</span></div></div>
233
+ <button id="provider-network-link" class="quiet network-link" type="button" hidden>配置此连接的出口 →</button>
234
+ <nav class="editor-tabs" aria-label="模型服务设置分组"><button type="button" data-provider-view="connection" aria-pressed="true">连接</button><button type="button" data-provider-view="models" aria-pressed="false">模型与用途</button><button type="button" data-provider-view="workflow" aria-pressed="false" hidden>ComfyUI 工作流</button></nav>
235
+ <form id="provider-form"><fieldset id="provider-fields">
236
+ <section id="provider-view-connection">
237
+ <label class="field-label" for="provider-preset">快速填写</label><select id="provider-preset"><option value="custom">自定义兼容服务</option><option value="openai">OpenAI · Images</option><option value="dashscope">百炼 · DashScope</option><option value="comfyui">ComfyUI · 已有服务</option></select><p id="provider-preset-note" class="field-note">按服务文档填写;编程订阅或聊天登录不等于媒体 API 认证。</p>
238
+ <div class="provider-two-fields"><div><label class="field-label" for="provider-name">名称</label><input id="provider-name" required maxlength="80" placeholder="例如:我的媒体服务" autocomplete="off"></div><div><label class="field-label" for="provider-auth">认证方式</label><select id="provider-auth"><option value="bearer">API Key</option><option value="none">无需认证</option></select></div></div>
239
+ <label class="field-label" for="provider-url">Base URL</label><input id="provider-url" type="url" required maxlength="2048" placeholder="https://example.com/v1" autocomplete="off">
240
+ <div class="provider-two-fields provider-credentials-fields"><div><label class="field-label" for="provider-key-action">凭据操作 <small id="provider-key-state"></small></label><select id="provider-key-action"><option value="keep">保留已有凭据</option><option value="replace">填写 / 替换密钥</option><option value="env">引用环境变量</option><option value="clear">清除凭据</option></select></div><div id="provider-key-field" hidden><label class="field-label" for="provider-key">新 API Key</label><input id="provider-key" type="password" autocomplete="new-password" maxlength="8192" spellcheck="false" placeholder="仅填写新密钥"></div><div id="provider-key-env-field" hidden><label class="field-label" for="provider-key-env">环境变量名称</label><input id="provider-key-env" maxlength="128" pattern="[A-Za-z_][A-Za-z0-9_]{0,127}" autocomplete="off" autocapitalize="off" spellcheck="false" placeholder="IRIS_MEDIA_KEY"><p class="field-note">只保存名称;值由 Core 进程环境提供,不读取 .env 文件。</p></div></div>
241
+ <label class="provider-enabled"><input id="provider-enabled" type="checkbox" checked> 启用此供应商</label>
242
+ <details id="provider-advanced" class="tool-details"><summary><span>高级连接设置</span><span class="disclosure">展开</span></summary><label class="field-label" for="provider-protocol">默认媒体协议</label><select id="provider-protocol"></select><label class="field-label" for="provider-media-url">媒体专用 Base URL(可选)</label><input id="provider-media-url" type="url" maxlength="2048" placeholder="留空沿用 Base URL"><p id="provider-id-note" class="field-note"></p></details>
243
+ </section>
244
+ <section id="provider-view-workflow" hidden>
245
+ <details id="comfyui-tools" class="tool-details" hidden>
246
+ <summary><span>ComfyUI 工作流 <small>文生图</small></span><span class="disclosure">展开</span></summary>
247
+ <p class="field-note">导入 → 确认节点 → 开放参数 → 预览。连接已有服务,一次接收一张图片。</p>
248
+ <div class="export-actions"><a id="comfyui-open" class="quiet" target="_blank" rel="noopener noreferrer" hidden>打开 ComfyUI ↗</a><label class="file-button secondary" for="comfyui-file">导入 API 工作流<input id="comfyui-file" type="file" accept="application/json,.json"></label></div>
249
+ <p id="comfyui-note" class="field-note" role="status">最多 40 KiB。支持 API 图和完整 Iris v0/v1 模板,导入不执行生成。</p>
250
+ <div id="comfyui-bindings" hidden>
251
+ <label class="field-label" for="comfyui-model">工作流名称 / 模型 ID</label><input id="comfyui-model" maxlength="120" placeholder="例如:my-sdxl">
252
+ <details class="comfy-group"><summary><span>输入与输出节点</span><span class="disclosure">展开</span></summary>
253
+ <label class="field-label" for="comfyui-prompt-node">正向提示词节点</label><select id="comfyui-prompt-node"></select>
254
+ <label class="field-label" for="comfyui-output-node">图片输出节点</label><select id="comfyui-output-node"></select>
255
+ <label class="field-label" for="comfyui-size-node">尺寸节点(可选)</label><select id="comfyui-size-node"></select>
256
+ </details>
257
+ <details id="comfyui-exposed" class="comfy-group"><summary><span>开放参数 <small id="comfyui-exposed-count">0 / 32</small></span><span class="disclosure">展开</span></summary><p class="field-note">勾选已有输入并命名。LoRA 模型与 CLIP 权重分别开放;不添加节点或安装模型。</p><div id="comfyui-slots"></div></details>
258
+ <section class="comfy-preview" aria-label="工作流表单预览"><div class="section-heading"><h3>使用时的表单</h3><span id="comfyui-preview-count" class="badge">固定工作流</span></div><div id="comfyui-preview"></div></section>
259
+ <p class="field-note">只读检查使用已保存连接;检查不保存、不入队。未开放的输入沿用模板,输出节点须恰好产生一张图。</p>
260
+ <div class="export-actions"><button id="comfyui-check" class="secondary" type="button">只读检查</button><button id="comfyui-add" class="secondary" type="button">加入模型草稿</button><button id="comfyui-discard" class="quiet" type="button">放弃导入</button></div>
261
+ <div id="comfyui-replace" class="comfy-confirm" role="group" aria-label="确认替换工作流" hidden><p>同名工作流已存在。替换后新调用使用新模板,旧任务保持原绑定。</p><div class="export-actions"><button id="comfyui-replace-yes" type="button">确认替换草稿</button><button id="comfyui-replace-no" class="quiet" type="button">取消</button></div></div>
262
+ </div>
263
+ </details>
264
+ </section>
265
+ <section id="provider-view-models" hidden>
266
+ <div class="section-heading provider-section"><h3>模型与用途</h3><button id="provider-discover" class="quiet" type="button">读取模型目录</button></div><p id="provider-directory-note" class="field-note">先保存连接,再读取目录;目录成功不代表媒体实测通过。</p>
267
+ <div class="provider-model-add"><input id="provider-model-id" maxlength="512" placeholder="手填模型 ID" aria-label="手填模型 ID" autocomplete="off"><button id="provider-model-add" class="secondary" type="button">添加</button></div>
268
+ <div id="provider-directory" hidden><input id="provider-directory-search" type="search" placeholder="搜索目录" aria-label="搜索模型目录"><div id="provider-directory-list"></div><p class="field-note">添加后请明确勾选用途。目录只提供参考,不自动批准调用。</p></div>
269
+ <p class="field-note">确认用途后可加入自动池;在“功能模型池”统一调整策略。</p><div id="provider-models"></div><p id="provider-models-empty" class="field-note">也可以先仅保存连接,稍后添加模型。</p>
270
+ </section>
271
+ <div class="provider-save-area"><p id="provider-save-summary" class="field-note"></p><div class="provider-footer"><button id="provider-save" type="submit">保存设置</button><button id="provider-cancel" class="quiet" type="button">取消编辑</button></div></div>
272
+ </fieldset></form>
273
+ <details id="provider-management-tools" class="tool-details"><summary><span>供应商管理</span><span class="disclosure">展开</span></summary><p id="provider-binding-warning" class="field-note">停用可恢复;修改连接或删除可能影响旧任务恢复,不会取消远端任务或退款。删除仅检查当前 Core 工作区的依赖。</p><div class="export-actions"><button id="provider-toggle" class="secondary" type="button">停用供应商</button><button id="provider-delete" class="quiet danger" type="button">删除供应商</button></div><div id="provider-delete-confirm" class="inline-confirm" hidden><p id="provider-delete-impact"></p><button id="provider-delete-yes" class="secondary danger" type="button">确认删除</button><button id="provider-delete-no" class="quiet" type="button">取消</button></div></details>
274
+ </section>
275
+ </div>
276
+ </section>
277
+ <section id="workspace" hidden aria-labelledby="studio-title">
278
+ <div class="page-heading"><div><p class="eyebrow">A LITTLE ROOM TO CREATE</p><h1 id="studio-title">让想法,有画面。</h1><p id="studio-note" class="muted">保留喜欢的部分,试一点新的可能。</p></div><button id="new-run" class="secondary" type="button">+ 新建流程</button></div>
279
+ <div class="studio-grid">
280
+ <details id="creation-settings" class="card composer" open>
281
+ <summary><span>创作设置 <small id="input-summary">从一张图片开始</small></span><span class="disclosure">收起</span></summary>
282
+ <form id="edit-form">
283
+ <fieldset id="draft-fields">
284
+ <div id="creation-modes" class="view-switch creation-modes" aria-label="创作方式"><button type="button" data-creation-mode="generate" aria-pressed="false">生成图片</button><button type="button" data-creation-mode="edit" aria-pressed="true">修改图片</button><button type="button" data-creation-mode="video" aria-pressed="false" hidden>生成视频</button><button type="button" data-creation-mode="tts" aria-pressed="false" hidden>语音合成</button><button type="button" data-creation-mode="transcribe" aria-pressed="false" hidden>音频转写</button></div>
285
+ <div id="source-input">
286
+ <label for="image-file" class="field-label">原图</label>
287
+ <label id="image-drop" class="image-drop" for="image-file"><img id="input-preview" alt="待创作的原图" hidden><span><strong id="file-name">选择一张图片</strong><small>点击或拖入 PNG / JPEG / WebP</small></span><span class="upload-arrow" aria-hidden="true">↗</span><input id="image-file" type="file" accept="image/png,image/jpeg,image/webp" aria-describedby="image-help"></label>
288
+ <p id="image-help" class="field-note">仅支持静态图片,最大 20 MiB。</p>
289
+ </div>
290
+ <div id="audio-source-input" hidden><label for="audio-file" class="field-label">原音频</label><label class="file-button secondary" for="audio-file">选择音频<input id="audio-file" type="file" accept="audio/wav,audio/x-wav,audio/mpeg,audio/ogg,audio/flac,.wav,.mp3,.ogg,.flac"></label><p id="audio-file-name" class="field-note">WAV / MP3 / OGG / FLAC,最大20 MiB。</p><audio id="audio-input-preview" controls preload="metadata" hidden></audio></div>
291
+ <label id="model-label" for="model" class="field-label">图片模型 <small>配置候选</small></label><select id="model" required><option value="">读取模型…</option></select>
292
+ <label id="prompt-label" for="edit-prompt" class="field-label">想改些什么?</label><textarea id="edit-prompt" rows="4" maxlength="12000" required placeholder="描述想保留的细节,以及想尝试的变化…"></textarea>
293
+ <details id="speech-options" class="tool-details" hidden><summary><span>音色(可选)</span><span class="disclosure">展开</span></summary><label for="speech-voice" class="field-label">模型支持的音色标识</label><input id="speech-voice" maxlength="64" placeholder="留空沿用协议默认值" autocomplete="off"><p class="field-note">按所选模型的要求填写,不同模型的音色名称可能不同。</p></details>
294
+ <section id="comfy-creation" class="comfy-studio" aria-label="ComfyUI 工作流参数" hidden><div class="section-heading"><h3>工作流参数</h3><span class="badge">ComfyUI</span></div><p id="comfy-creation-summary" class="field-note"></p><div id="comfy-creation-fields"></div><button id="comfy-creation-check" type="button" class="quiet inline-button">检查参数并读取选项</button><p id="comfy-creation-note" class="field-note" role="status">尚未检查,不会自动生成。</p></section>
295
+ <details id="advanced-settings" class="tool-details"><summary><span>高级参数</span><span class="disclosure">展开</span></summary><label for="edit-size" class="field-label">输出尺寸(可选)</label><input id="edit-size" maxlength="64" placeholder="使用模型默认值" autocomplete="off"><p id="edit-size-note" class="field-note">填写模型支持的尺寸;留空使用默认值。</p><div id="video-duration-field" hidden><label for="video-duration" class="field-label">时长(秒,可选)</label><input id="video-duration" type="number" min="1" max="60" step="any" placeholder="使用模型默认值"><p class="field-note">填写所选模型支持的时长(1–60 秒);目录不代表参数已实测。</p></div></details>
296
+ </fieldset>
297
+ <div class="model-management"><button id="manage-models" class="quiet inline-button" type="button">管理模型 ↗</button></div>
298
+ <button id="start-edit" class="full" type="submit" disabled>开始改图</button>
299
+ <p id="creation-help" class="field-note">读取权限中…</p>
300
+ <p id="creation-feedback" role="status" aria-live="polite" hidden></p>
301
+ </form>
302
+ <details id="model-panel" class="compact-details"><summary><span>模型与配置 <small id="model-summary">读取中</small></span><span class="disclosure">展开</span></summary><p id="model-note" class="muted"></p><ul id="model-list"></ul></details>
303
+ <p id="locked-note" class="composer-note" hidden>此流程的输入已固定。想换个要求,可以新建流程。</p>
304
+ </details>
305
+ <section id="viewer" class="card viewer" aria-label="流程与作品" aria-busy="false">
306
+ <div class="canvas-toolbar"><span class="canvas-label">创作画布</span><div id="view-modes" class="view-switch" aria-label="比较方式"><button type="button" data-view="pair" aria-pressed="true">并排</button><button type="button" data-view="overlay" aria-pressed="false" disabled>叠图</button></div><button id="refresh" class="quiet" type="button">刷新</button></div>
307
+ <div id="viewer-empty" class="viewer-empty"><img id="draft-preview" alt="待改图的本地预览" hidden><span class="empty-mark" aria-hidden="true">✧</span><h2>从一张图片开始</h2><p class="muted">选好原图,写下想法。作品会保存在当前工作区。</p></div>
308
+ <div id="run-view" hidden>
309
+ <section id="video-result" class="video-result" hidden aria-label="视频结果"><p class="eyebrow">MOTION</p><h3>让想法动起来</h3><video id="output-video" controls playsinline preload="metadata" hidden></video><p id="video-result-note" class="field-note" role="status">原视频会保存在当前工作区。</p></section>
310
+ <section id="audio-result" class="audio-result" hidden aria-label="音频与转写结果"><div class="audio-result-header"><span class="audio-result-icon" aria-hidden="true">♪</span><div><p class="eyebrow" id="audio-result-kind">AUDIO</p><h3 id="audio-result-title">原任务的作品</h3></div></div><div id="audio-source-result" hidden><p class="field-label">原音频</p><audio id="source-audio" controls preload="metadata"></audio></div><div id="audio-output-result" hidden><p class="field-label">合成语音</p><audio id="output-audio" controls preload="metadata"></audio></div><pre id="transcript-result" class="transcript-result" hidden></pre><p id="audio-result-note" class="field-note" role="status"></p></section>
311
+ <div id="image-pair" class="image-pair">
312
+ <figure id="source-card" class="image-card"><figcaption><span>原图</span><small id="source-selected" class="selected-label" hidden>已选择</small></figcaption><button id="source-preview" class="image-stage" type="button" aria-label="放大原图"><span id="source-placeholder" class="muted">读取中…</span><img id="source-image" alt="此流程保存的原图" hidden></button><p id="source-dimensions" class="image-dimensions"></p><button id="select-source" class="choice-button" type="button" aria-pressed="false" disabled>选择原图</button></figure>
313
+ <figure id="output-card" class="image-card"><figcaption><span>生成结果</span><small id="output-selected" class="selected-label" hidden>已选择</small></figcaption><button id="output-preview" class="image-stage" type="button" aria-label="放大生成结果"><span id="output-placeholder" class="muted">尚无已保存的结果</span><img id="output-image" alt="此流程保存的生成结果" hidden></button><p id="output-dimensions" class="image-dimensions"></p><button id="select-output" class="choice-button" type="button" aria-pressed="false" disabled>选择结果</button></figure>
314
+ </div>
315
+ <div id="overlay-view" class="overlay-view" hidden><div class="overlay-stage"><img id="overlay-source" alt="叠图原图"><img id="overlay-output" alt="叠图结果"></div><label for="compare-split">原图 / 结果分界<input id="compare-split" type="range" min="0" max="100" value="50"></label></div>
316
+ <details id="plugin-preview" class="plugin-preview compact-details" hidden>
317
+ <summary><span>扩展预览</span><span class="disclosure">展开</span></summary>
318
+ <div class="plugin-preview-options"><label>作品<select id="plugin-artifact" aria-label="扩展预览作品"></select></label><label>查看方式<select id="plugin-renderer" aria-label="作品预览方式"></select></label></div>
319
+ <div id="plugin-preview-slot" class="plugin-slot"></div>
320
+ </details>
321
+ <div class="run-heading"><div><h2 id="status-title"></h2><p id="status-message" class="muted"></p></div><button id="stop-operation" class="secondary" type="button" hidden>停止等待</button></div>
322
+ <p id="operation-note" class="field-note" hidden></p>
323
+ <div class="result-actions"><p id="selection-feedback" role="status" aria-live="polite">选择喜欢的版本,再保存到设备。</p><button id="download" type="button" disabled>下载已选作品</button></div>
324
+ <div class="reuse-actions"><button id="reuse-selected" class="quiet" type="button" disabled>用已选作品新建</button><span id="run-meta" class="meta"></span></div>
325
+ <details id="run-details" class="run-details"><summary><span>流程详情</span><span class="disclosure">展开</span></summary><section class="prompt-section" aria-labelledby="prompt-title"><h3 id="prompt-title">修改要求</h3><p id="prompt"></p></section><section id="run-parameters" class="comfy-record" hidden><h3>本次记录的工作流参数</h3><dl id="run-parameter-values"></dl><p class="field-note">来自此流程的输入快照;未记录的输入沿用当时模板。</p></section><dl id="run-facts"></dl><p class="muted">像素差异只描述图片变化,不代表质量评分。</p></details>
326
+ </div>
327
+ </section>
328
+ </div>
329
+ </section>
330
+ <footer>Iris · 本地创作,随时接续<span>面向 0.3 的 Core 工作台</span></footer>
331
+ </main>
332
+ </div></div>
333
+ <dialog id="image-dialog" aria-labelledby="image-dialog-title"><div class="section-heading"><h2 id="image-dialog-title">图片预览</h2><button id="close-image-dialog" class="quiet" type="button" aria-label="关闭图片预览">关闭</button></div><img id="expanded-image" alt="放大的作品"><p class="field-note">显示原始图片,不改变作品像素。</p></dialog>
334
+ <dialog id="appearance-dialog" class="appearance-dialog" aria-labelledby="appearance-title">
335
+ <div class="section-heading"><h2 id="appearance-title">外观</h2><button id="appearance-close" class="quiet" type="button">关闭</button></div>
336
+ <div class="iris-swatch" aria-label="鸢尾六色渐变"></div><p class="field-note">一点鸢尾色,留白给创作。设置仅保存在此浏览器。</p>
337
+ <label class="field-label" for="appearance-theme">颜色模式</label><select id="appearance-theme"><option value="light">浅色</option><option value="dark">深色</option><option value="system">跟随系统</option></select>
338
+ <label class="field-label" for="appearance-density">界面密度</label><select id="appearance-density"><option value="comfortable">舒适</option><option value="compact">紧凑</option></select>
339
+ <details id="appearance-background" class="tool-details"><summary><span>自选背景</span><span class="disclosure">展开</span></summary><label class="file-button secondary" for="appearance-image">选择本地图片<input id="appearance-image" type="file" accept="image/png,image/jpeg,image/webp" disabled></label><p id="appearance-image-note" class="field-note">没有自选背景。图片不会上传到 Core。</p><p class="field-note">PNG / JPEG / WebP,最大 5 MiB;图片比较区保持中性底色。</p><label class="field-label" for="appearance-position">位置</label><select id="appearance-position"><option value="center">居中</option><option value="top">顶部</option><option value="bottom">底部</option></select><label class="field-label" for="appearance-overlay">遮罩 <output id="appearance-overlay-value">86%</output></label><input id="appearance-overlay" type="range" min="50" max="100" value="86"><label class="field-label" for="appearance-blur">模糊 <output id="appearance-blur-value">0 px</output></label><input id="appearance-blur" type="range" min="0" max="20" value="0"><button id="appearance-remove" class="quiet" type="button" disabled>移除背景</button></details>
340
+ <details class="tool-details"><summary><span>分享外观设置</span><span class="disclosure">展开</span></summary><p class="field-note">JSON 只包含配色与显示设置,不包含背景图片、连接或密钥。</p><div class="export-actions"><button id="appearance-export" class="quiet" type="button">导出设置</button><label class="file-button secondary" for="appearance-import">导入设置<input id="appearance-import" type="file" accept="application/json,.json"></label></div></details>
341
+ <div class="export-actions"><button id="appearance-reset" class="quiet" type="button">恢复默认配色与布局</button></div><p id="appearance-note" class="field-note" role="status" aria-live="polite">更改即时生效。</p>
342
+ </dialog>
343
+ </body>
344
+ </html>