@xmanrui/dsh-im 4.25.0 → 4.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -136,7 +136,7 @@ A successful request returns:
136
136
  { "sent": true }
137
137
  ```
138
138
 
139
- The body accepts exactly `botId`, `targetId`, and `text`, with a maximum total JSON size of 1 MiB. Do not add a native platform route, `sessionId`, `chatRef`, temporary webhook, or `idempotencyKey`.
139
+ The body accepts the required `botId`, `targetId`, and `text` fields, plus optional `format` (`plain` or `markdown`, default `plain`), with a maximum total JSON size of 1 MiB. Do not add a native platform route, `sessionId`, `chatRef`, temporary webhook, or `idempotencyKey`.
140
140
 
141
141
  The fixed endpoint is `POST /api/dsh-im/delivery/messages`. It reuses the current DSH Host WebServer and does not open another port. Port `3080` is the default for the Web profile; use the address printed by the running Host when it differs.
142
142
 
@@ -164,12 +164,20 @@ export async function apply(ctx) {
164
164
  }
165
165
  ```
166
166
 
167
- In a real plugin, call `ctx.dshIm.send()` from your existing scheduled job, build callback, or business-event handler. Its optional fourth argument currently supports an abort signal:
167
+ In a real plugin, call `ctx.dshIm.send()` from your existing scheduled job, build callback, or business-event handler. Its optional fourth argument supports an abort signal and a text format:
168
168
 
169
169
  ```js
170
- await ctx.dshIm.send(botId, targetId, text, { signal });
170
+ await ctx.dshIm.send(botId, targetId, text, { signal }); // Keep existing default behavior
171
+ await ctx.dshIm.send(botId, targetId, '# Daily report\n\n**Checks complete**', {
172
+ signal,
173
+ format: 'markdown',
174
+ });
171
175
  ```
172
176
 
177
+ `format` accepts only `plain` and `markdown`, defaulting to `plain`. Markdown formatting is currently implemented for Feishu/Lark: both direct and group destinations receive a native Markdown card without starting a Session or a stream. Other channels retain their existing delivery behavior; Markdown rendering is not guaranteed there. HTTP and `message.send` RPC accept the same optional `format` field in their payloads.
178
+
179
+ The original Markdown, including whitespace, is preserved without silent truncation or automatic splitting; platform message-size and Markdown-syntax limits still apply. Rejection, timeout, and cancellation use the existing error handling, with no automatic plain-text resend that could duplicate delivery. Older dsh-im Host APIs may ignore this option; both the consumer and dsh-im must load the updated code.
180
+
173
181
  A same-Host plugin may also list the saved targets for one bot:
174
182
 
175
183
  ```js
@@ -225,7 +233,7 @@ const result = await callDelivery(connection, 'message.send', {
225
233
  // result: { sent: true }
226
234
  ```
227
235
 
228
- `message.send` accepts exactly `{ botId, targetId, text }`. Do not add a native route, `sessionId`, `chatRef`, temporary webhook, or `idempotencyKey`.
236
+ `message.send` accepts `{ botId, targetId, text, format? }`; `format` must be `plain` or `markdown`. Do not add a native route, `sessionId`, `chatRef`, temporary webhook, or `idempotencyKey`.
229
237
 
230
238
  ### Example: deliver a daily report
231
239
 
@@ -136,7 +136,7 @@ curl --request POST \
136
136
  { "sent": true }
137
137
  ```
138
138
 
139
- 请求体严格只接受 `botId`、`targetId` `text`,JSON 总大小不能超过 1 MiB。不要附加平台原生路由、`sessionId`、`chatRef`、临时 Webhook 或 `idempotencyKey`。
139
+ 请求体接受必填的 `botId`、`targetId`、`text` 和可选的 `format`(`plain` 或 `markdown`,默认 `plain`),JSON 总大小不能超过 1 MiB。不要附加平台原生路由、`sessionId`、`chatRef`、临时 Webhook 或 `idempotencyKey`。
140
140
 
141
141
  接口路径固定为 `POST /api/dsh-im/delivery/messages`,复用当前 DSH Host 的 WebServer,不会另开端口。示例中的 `3080` 是 Web profile 的默认端口;实际地址以 Host 启动时显示的地址为准。
142
142
 
@@ -164,12 +164,20 @@ export async function apply(ctx) {
164
164
  }
165
165
  ```
166
166
 
167
- 实际使用时,把 `ctx.dshIm.send()` 放进你的定时任务、构建回调或业务事件处理函数中。可选的第四个参数当前支持取消信号:
167
+ 实际使用时,把 `ctx.dshIm.send()` 放进你的定时任务、构建回调或业务事件处理函数中。可选的第四个参数支持取消信号和文本格式:
168
168
 
169
169
  ```js
170
- await ctx.dshIm.send(botId, targetId, text, { signal });
170
+ await ctx.dshIm.send(botId, targetId, text, { signal }); // 保持原有默认发送行为
171
+ await ctx.dshIm.send(botId, targetId, '# 每日报告\n\n**检查完成**', {
172
+ signal,
173
+ format: 'markdown',
174
+ });
171
175
  ```
172
176
 
177
+ `format` 只接受 `plain` 和 `markdown`,省略时为 `plain`。当前 Markdown 格式适配用于飞书/Lark:私聊和群聊均通过原生 Markdown 卡片发送,不启动会话或流式输出;其他渠道保留原有发送行为,不保证 Markdown 渲染。HTTP 和 `message.send` RPC 可在请求体中添加同名 `format` 字段。
178
+
179
+ Markdown 原文(含换行)完整传递,不进行静默截断或自动分段;消息仍受平台大小和 Markdown 语法限制。平台拒绝、超时或取消时沿用已有错误处理,不自动回退成纯文本重发,以免重复投递。旧版本 dsh-im 的 Host API 可能忽略这个新选项;调用方与 dsh-im 都需要加载支持该选项的代码。
180
+
173
181
  同 Host 插件也可以列出某个机器人的已保存目标:
174
182
 
175
183
  ```js
@@ -225,7 +233,7 @@ const result = await callDelivery(connection, 'message.send', {
225
233
  // result: { sent: true }
226
234
  ```
227
235
 
228
- `message.send` 只接受 `{ botId, targetId, text }`。不要附加平台路由、`sessionId`、`chatRef`、临时 Webhook 或 `idempotencyKey`。
236
+ `message.send` 接受 `{ botId, targetId, text, format? }`;`format` 只允许 `plain` 或 `markdown`。不要附加平台路由、`sessionId`、`chatRef`、临时 Webhook 或 `idempotencyKey`。
229
237
 
230
238
  ### 示例:投递每日报告
231
239
 
package/README.en.md CHANGED
@@ -251,7 +251,9 @@ Startup configuration validation failures also include `file`, `field`, and `iss
251
251
 
252
252
  ## Local development
253
253
 
254
- The Web profile is verified with unmodified DSH `0.1.2-alpha.4`, `0.1.2-alpha.5`, `0.1.2-rc.1`, `0.1.3-alpha.1`, and `0.1.5-alpha.1`. All use the same dsh-im management RPC adapter through the public Connection `/api` Fetch registry; no DSH patch or rebuild is required. After upgrading the plugin, restart the Host and refresh the settings page so both sides use the same plugin build.
254
+ The latest dsh-im follows the latest DSH, with DSH `0.1.7-alpha.1` (Session format V4) as this update's supported baseline. New features and fixes do not add compatibility branches for older DSH versions; existing unrelated compatibility code remains in place. Older hosts should use the corresponding historical plugin release. `package.json` declares only the host versions actually verified for this build, without promising support for untested future releases. After upgrading the plugin, restart the Host and refresh the settings page so both sides use the same plugin build.
255
+
256
+ Source details, guidance, and quoted replies now use the V4 `plugin:dsh-im` source kind, fixing `SessionFormatError: format v4 message requires a producer-owned source kind`. Message ordering, user text, and session-level guidance deduplication retain their existing behavior. The host owns historical Session migration.
255
257
 
256
258
  ```sh
257
259
  npm install
@@ -261,6 +263,8 @@ node bin/dsh-im.mjs install --source .
261
263
 
262
264
  `npm run check` runs unit tests, builds the Host and Client artifacts, and verifies that the published package contains neither credentials nor standalone channel settings-page registrations.
263
265
 
266
+ After building, run `node scripts/verify-injected-context.mjs /path/to/built/deepseek-harness` to exercise the bundled context hook against real DSH V4 JSONL persistence. It covers plain messages, source details, guidance, quoted replies, combined blocks, and multipart text, including reopening the log and appending another turn. The script loads components from the supplied host and cleans up its temporary Session directory; no bot credentials or model requests are needed.
267
+
264
268
  IM management uses Harness browser authentication and Host/Origin trust checks by default. Once Harness allows and authenticates access from your LAN address, you can view and configure IM bots without any extra dsh-im configuration.
265
269
 
266
270
  When accessing DSH through a custom domain, if IM settings report `transport failure for /api/dsh-im/...: HTTP 403`, add the browser-facing domain to your existing DSH launch command and restart DSH:
package/README.md CHANGED
@@ -254,7 +254,9 @@ Logo 由 dsh-im 的浏览器适配显示,无需修改 DSH。适配保留原始
254
254
 
255
255
  ## 本地开发
256
256
 
257
- Web profile 已验证兼容原版 DSH `0.1.2-alpha.4`、`0.1.2-alpha.5`、`0.1.2-rc.1`、`0.1.3-alpha.1` `0.1.5-alpha.1`。这些版本共用 dsh-im 的管理 RPC 适配,通过 Connection 的公开 `/api` Fetch 注册接口工作,无需修改或重新编译 DSH。升级插件后重启 Host 并刷新设置页,使 Host 和客户端使用同一版插件。
257
+ 最新版 dsh-im 跟随最新版 DSH,本次支持基线为 DSH `0.1.7-alpha.1`(Session 格式 v4)。后续功能和修复不再增加旧版 DSH 的兼容分支,已有其他兼容逻辑暂时保留;旧宿主请使用对应的历史插件版本。`package.json` 只声明当前实际验证的宿主版本,不承诺未经验证的未来版本。升级插件后重启 Host 并刷新设置页,使 Host 和客户端使用同一版插件。
258
+
259
+ 上下文增强中的来源信息、引导词和引用回复使用 v4 的 `plugin:dsh-im` 来源字段,修复了它们触发的 `SessionFormatError: format v4 message requires a producer-owned source kind`。消息顺序、用户正文和会话级引导词去重沿用原有机制,历史会话由宿主负责迁移。
258
260
 
259
261
  ```sh
260
262
  npm install
@@ -264,6 +266,8 @@ node bin/dsh-im.mjs install --source .
264
266
 
265
267
  `npm run check` 运行单元测试、构建 Host/Client 产物,并验证发布包不包含凭据或独立渠道设置页注册。
266
268
 
269
+ 构建后运行 `node scripts/verify-injected-context.mjs /path/to/built/deepseek-harness`,验证发布产物中的上下文钩子能通过真实 DSH v4 JSONL 持久化,覆盖普通消息、来源信息、引导词、引用、组合和多段文本,以及关闭后重新读取、继续写入下一轮。脚本从指定宿主加载组件,使用并清理临时会话目录,无需机器人凭据或模型请求。
270
+
267
271
  IM 管理接口默认沿用 Harness 的浏览器认证和 Host/Origin 信任检查。只要 Harness 已允许并认证当前局域网访问,便可直接查看和配置 IM 机器人,无需额外修改 dsh-im 配置。
268
272
 
269
273
  通过自定义域名访问时,如果 IM 设置页出现 `transport failure for /api/dsh-im/...: HTTP 403`,请在原 DSH 启动命令中添加浏览器访问的域名,并重启 DSH:
package/lib/client.js CHANGED
@@ -595,7 +595,7 @@ var React34 = __toESM(require("react"), 1);
595
595
  // package.json
596
596
  var package_default = {
597
597
  name: "@xmanrui/dsh-im",
598
- version: "4.25.0",
598
+ version: "4.26.0",
599
599
  description: "\u628A\u5341\u4E8C\u79CD IM \u6E20\u9053\u548C\u516C\u7F51 AI Office \u63A5\u5165\u672C\u673A DeepSeek Harness\u3002 Connect twelve IM channels and a public AI Office to a local DeepSeek Harness.",
600
600
  keywords: [
601
601
  "deepseek-harness",
@@ -711,6 +711,7 @@ var package_default = {
711
711
  "lib",
712
712
  "plugin-src",
713
713
  "scripts/verify-interface-language.mjs",
714
+ "scripts/verify-injected-context.mjs",
714
715
  "scripts/verify-lan-management.mjs",
715
716
  "scripts/verify-model-setting.mjs",
716
717
  "scripts/verify-package.mjs",
@@ -740,13 +741,9 @@ var package_default = {
740
741
  platform: "web"
741
742
  },
742
743
  compatibility: {
743
- dsh: "0.1.2-alpha.4 || 0.1.2-alpha.5 || 0.1.2-rc.1 || 0.1.3-alpha.1 || 0.1.5-alpha.1",
744
+ dsh: "0.1.7-alpha.1",
744
745
  dshReleases: {
745
- "0.1.2-alpha.4": "compatible",
746
- "0.1.2-alpha.5": "compatible",
747
- "0.1.2-rc.1": "compatible",
748
- "0.1.3-alpha.1": "compatible",
749
- "0.1.5-alpha.1": "compatible"
746
+ "0.1.7-alpha.1": "compatible"
750
747
  },
751
748
  profiles: [
752
749
  "web"
@@ -1010,6 +1007,7 @@ var image_input_default = {
1010
1007
  "\u6A21\u578B\u56FE\u7247\u603B\u91CF\u4E0A\u9650 (MB)": "Model total image limit (MB)",
1011
1008
  "\u6BCF\u6761\u6D88\u606F\u6700\u591A\u56FE\u7247\u6570": "Maximum images per message",
1012
1009
  "\u56FE\u7247\u8F93\u5165": "Image input",
1010
+ "\u67E5\u770B\u56FE\u7247\u8F93\u5165\u8BF4\u660E": "View image input details",
1013
1011
  "\u9002\u7528\u4E8E\u652F\u6301\u56FE\u7247\u7684\u804A\u5929\u6E20\u9053\u3002\u539F\u56FE\u6309\u9644\u4EF6\u4FDD\u7559\u65F6\u957F\u4FDD\u5B58\uFF0C\u53D1\u9001\u7ED9\u6A21\u578B\u7684\u526F\u672C\u4F1A\u81EA\u52A8\u7F29\u653E\u6216\u538B\u7F29\uFF1B\u65E0\u6CD5\u76F4\u63A5\u53D1\u9001\u65F6\u4EA4\u7ED9\u6A21\u578B\u6309\u6587\u4EF6\u5904\u7406\u3002": "Applies to chat channels that support images. Originals follow attachment retention settings. Model copies are resized or compressed automatically; images that cannot be sent directly are provided as files.",
1014
1012
  "\u4FDD\u5B58\u56FE\u7247\u8BBE\u7F6E": "Save image settings",
1015
1013
  "\u6B63\u5728\u8BFB\u53D6\u56FE\u7247\u8BBE\u7F6E\u2026": "Loading image settings\u2026"
@@ -1314,6 +1312,10 @@ var EN = Object.freeze({
1314
1312
  "\u5F53\u524D\u7248\u672C": "Current version",
1315
1313
  "DSH-IM \u66F4\u65B0": "DSH-IM update",
1316
1314
  "\u68C0\u67E5\u66F4\u65B0": "Check for updates",
1315
+ "DSH \u7248\u672C\u517C\u5BB9\u8BF4\u660E": "DSH version compatibility",
1316
+ "dsh-im 4.25.0 \u652F\u6301\u5230 DSH v0.1.6-alpha.2\u3002": "dsh-im 4.25.0 supports DSH up to v0.1.6-alpha.2.",
1317
+ "dsh-im 4.26.0 \u4EC5\u652F\u6301 DSH v0.1.7-alpha.1\u3002": "dsh-im 4.26.0 only supports DSH v0.1.7-alpha.1.",
1318
+ "\u5347\u7EA7\u5230 dsh-im 4.26.0 \u524D\uFF0C\u8BF7\u5148\u5C06 DSH \u5347\u7EA7\u5230 v0.1.7-alpha.1\uFF1B\u4F7F\u7528\u65E7\u7248 DSH \u8BF7\u4FDD\u7559 dsh-im 4.25.0\u3002": "Before updating to dsh-im 4.26.0, upgrade DSH to v0.1.7-alpha.1. If you use an older DSH version, stay on dsh-im 4.25.0.",
1317
1319
  "\u91CD\u65B0\u68C0\u67E5": "Check again",
1318
1320
  "\u5237\u65B0\u72B6\u6001": "Refresh status",
1319
1321
  "\u624B\u5DE5\u66F4\u65B0": "Manual update",
@@ -18132,37 +18134,67 @@ function ImageInputSettings({ rpcCall }) {
18132
18134
  ];
18133
18135
  return h2(
18134
18136
  "section",
18135
- { className: "dim-globalSection", "aria-label": "\u56FE\u7247\u8F93\u5165", "aria-busy": phase === "loading" || phase === "saving" },
18136
- h2("h3", null, "\u56FE\u7247\u8F93\u5165"),
18137
- h2("p", null, "\u9002\u7528\u4E8E\u652F\u6301\u56FE\u7247\u7684\u804A\u5929\u6E20\u9053\u3002\u539F\u56FE\u6309\u9644\u4EF6\u4FDD\u7559\u65F6\u957F\u4FDD\u5B58\uFF0C\u53D1\u9001\u7ED9\u6A21\u578B\u7684\u526F\u672C\u4F1A\u81EA\u52A8\u7F29\u653E\u6216\u538B\u7F29\uFF1B\u65E0\u6CD5\u76F4\u63A5\u53D1\u9001\u65F6\u4EA4\u7ED9\u6A21\u578B\u6309\u6587\u4EF6\u5904\u7406\u3002"),
18137
+ { className: "dim-globalSection dim-imageSettings", "aria-label": "\u56FE\u7247\u8F93\u5165", "aria-busy": phase === "loading" || phase === "saving" },
18138
+ h2(
18139
+ "div",
18140
+ { className: "dim-globalHead" },
18141
+ h2(
18142
+ "div",
18143
+ { className: "dim-globalHeadTitle" },
18144
+ h2("h3", null, "\u56FE\u7247\u8F93\u5165"),
18145
+ h2(
18146
+ "div",
18147
+ { className: "dim-globalTtlHelp" },
18148
+ h2("button", {
18149
+ type: "button",
18150
+ className: "dim-channelHelpButton dim-globalTtlHelpButton",
18151
+ "aria-label": "\u67E5\u770B\u56FE\u7247\u8F93\u5165\u8BF4\u660E",
18152
+ "aria-describedby": `${id6}-help`
18153
+ }, h2("span", { "aria-hidden": "true" }, "?")),
18154
+ h2(
18155
+ "div",
18156
+ { id: `${id6}-help`, className: "dim-globalTtlTooltip dim-imageSettingsTooltip", role: "tooltip" },
18157
+ "\u9002\u7528\u4E8E\u652F\u6301\u56FE\u7247\u7684\u804A\u5929\u6E20\u9053\u3002\u539F\u56FE\u6309\u9644\u4EF6\u4FDD\u7559\u65F6\u957F\u4FDD\u5B58\uFF0C\u53D1\u9001\u7ED9\u6A21\u578B\u7684\u526F\u672C\u4F1A\u81EA\u52A8\u7F29\u653E\u6216\u538B\u7F29\uFF1B\u65E0\u6CD5\u76F4\u63A5\u53D1\u9001\u65F6\u4EA4\u7ED9\u6A21\u578B\u6309\u6587\u4EF6\u5904\u7406\u3002"
18158
+ )
18159
+ )
18160
+ )
18161
+ ),
18138
18162
  h2(
18139
18163
  "form",
18140
18164
  { onSubmit: save },
18141
- ...fields.map(([key, label]) => h2(
18165
+ h2(
18142
18166
  "div",
18143
- { className: "dim-globalTtlRow", key },
18144
- h2("label", { htmlFor: `${id6}-${key}` }, label),
18145
- h2("input", {
18146
- id: `${id6}-${key}`,
18147
- className: "dim-globalTtlInput",
18148
- type: "number",
18149
- min: 1,
18150
- step: 1,
18151
- value: values[key],
18152
- disabled: phase !== "ready",
18153
- onChange: (event) => {
18154
- setValues((current) => ({ ...current, [key]: event.target.value }));
18155
- setSaved(false);
18156
- setError(null);
18157
- }
18158
- })
18159
- )),
18160
- h2(GlobalButton, { type: "submit", kind: "primary", disabled: phase !== "ready" }, phase === "saving" ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58\u56FE\u7247\u8BBE\u7F6E"),
18161
- phase === "error" ? h2(GlobalButton, { onClick: () => void load() }, "\u91CD\u8BD5") : null
18167
+ { className: "dim-imageSettingsFields" },
18168
+ ...fields.map(([key, label]) => h2(
18169
+ "div",
18170
+ { className: "dim-imageSettingsField", key },
18171
+ h2("label", { htmlFor: `${id6}-${key}` }, label),
18172
+ h2("input", {
18173
+ id: `${id6}-${key}`,
18174
+ className: "dim-globalTtlInput",
18175
+ type: "number",
18176
+ min: 1,
18177
+ step: 1,
18178
+ value: values[key],
18179
+ disabled: phase !== "ready",
18180
+ onChange: (event) => {
18181
+ setValues((current) => ({ ...current, [key]: event.target.value }));
18182
+ setSaved(false);
18183
+ setError(null);
18184
+ }
18185
+ })
18186
+ ))
18187
+ ),
18188
+ h2(
18189
+ "div",
18190
+ { className: "dim-imageSettingsActions" },
18191
+ h2(GlobalButton, { type: "submit", kind: "primary", className: "dim-globalSaveButton", disabled: phase !== "ready" }, phase === "saving" ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58\u56FE\u7247\u8BBE\u7F6E"),
18192
+ phase === "error" ? h2(GlobalButton, { className: "dim-globalSaveButton", onClick: () => void load() }, "\u91CD\u8BD5") : null
18193
+ )
18162
18194
  ),
18163
- error ? h2("p", { role: "alert" }, error) : null,
18164
- saved ? h2("p", { role: "status" }, "\u5DF2\u4FDD\u5B58") : null,
18165
- phase === "loading" ? h2("p", { role: "status" }, "\u6B63\u5728\u8BFB\u53D6\u56FE\u7247\u8BBE\u7F6E\u2026") : null
18195
+ error ? h2("p", { className: "dim-globalInline dim-imageSettingsFeedback", "data-tone": "error", role: "alert" }, error) : null,
18196
+ saved ? h2("p", { className: "dim-globalInline dim-imageSettingsFeedback", role: "status" }, "\u5DF2\u4FDD\u5B58") : null,
18197
+ phase === "loading" ? h2("p", { className: "dim-globalInline dim-imageSettingsFeedback", role: "status" }, "\u6B63\u5728\u8BFB\u53D6\u56FE\u7247\u8BBE\u7F6E\u2026") : null
18166
18198
  );
18167
18199
  }
18168
18200
  function GlobalSettingsPanel({ rpcCall }) {
@@ -19142,6 +19174,20 @@ var CSS15 = String.raw`
19142
19174
  .dim-generalSettingsTab:focus-visible { outline: 2px solid var(--dim-blue); outline-offset: -2px; border-radius: 5px; }
19143
19175
  .dim-generalSettingsTabPanel { min-width: 0; padding-top: 14px; }
19144
19176
  .dim-globalSection { min-width: 0; padding: 14px 16px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 12px; background: var(--dsw-alias-bg-layer-3, #fff); }
19177
+ .dim-globalSection + .dim-globalSection { margin-top: 12px; }
19178
+ .dim-imageSettings { container-type: inline-size; }
19179
+ .dim-imageSettings .dim-globalHead { position: relative; }
19180
+ .dim-imageSettings .dim-globalTtlHelp { position: static; }
19181
+ .dim-globalTtlTooltip.dim-imageSettingsTooltip { width: min(320px, 100%); max-width: none; color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 17px; white-space: normal; overflow-wrap: anywhere; }
19182
+ .dim-imageSettingsFields { min-width: 0; display: grid; gap: 12px; margin-top: 12px; }
19183
+ .dim-imageSettingsField { min-width: 0; display: grid; grid-template-columns: minmax(0, 220px) minmax(0, 160px); align-items: center; gap: 6px 16px; }
19184
+ .dim-imageSettingsField label { min-width: 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 20px; overflow-wrap: anywhere; }
19185
+ .dim-imageSettingsField .dim-globalTtlInput { width: 100%; min-width: 0; }
19186
+ .dim-imageSettingsActions { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
19187
+ .dim-globalInline.dim-imageSettingsFeedback { margin: 10px 0 0; }
19188
+ @container (max-width: 380px) {
19189
+ .dim-imageSettingsField { grid-template-columns: minmax(0, 1fr); }
19190
+ }
19145
19191
  .dim-globalHead { min-width: 0; display: flex; align-items: center; }
19146
19192
  .dim-globalHeadTitle { min-width: 0; display: inline-flex; align-items: center; gap: 6px; }
19147
19193
  .dim-globalHead h3 { min-width: 0; overflow: hidden; margin: 0; color: var(--dsw-alias-label-primary, #1f2329); font-size: 15px; line-height: 22px; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; }
@@ -20014,6 +20060,18 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
20014
20060
  { className: "dim-updateHint" },
20015
20061
  "\u8BF7\u5728\u673A\u5668\u4EBA\u7A7A\u95F2\u65F6\u5B89\u88C5\uFF1B\u5B89\u88C5\u4F1A\u4FEE\u6539\u5F53\u524D profile \u7684\u4F9D\u8D56\uFF0C\u5B8C\u6210\u540E\u9700\u624B\u52A8\u91CD\u542F\u3002"
20016
20062
  ) : null,
20063
+ h2(
20064
+ "aside",
20065
+ { className: "dim-updateHint", "aria-label": "DSH \u7248\u672C\u517C\u5BB9\u8BF4\u660E" },
20066
+ h2("strong", null, "DSH \u7248\u672C\u517C\u5BB9\u8BF4\u660E"),
20067
+ h2("p", { className: "dim-updateManualHint" }, "dsh-im 4.25.0 \u652F\u6301\u5230 DSH v0.1.6-alpha.2\u3002"),
20068
+ h2("p", { className: "dim-updateManualHint" }, "dsh-im 4.26.0 \u4EC5\u652F\u6301 DSH v0.1.7-alpha.1\u3002"),
20069
+ h2(
20070
+ "p",
20071
+ { className: "dim-updateManualHint" },
20072
+ "\u5347\u7EA7\u5230 dsh-im 4.26.0 \u524D\uFF0C\u8BF7\u5148\u5C06 DSH \u5347\u7EA7\u5230 v0.1.7-alpha.1\uFF1B\u4F7F\u7528\u65E7\u7248 DSH \u8BF7\u4FDD\u7559 dsh-im 4.25.0\u3002"
20073
+ )
20074
+ ),
20017
20075
  h2(ManualUpdateCommand, {
20018
20076
  key: manualCommand ?? "unavailable",
20019
20077
  command: manualCommand,