dsh-ui-block:对话中渲染 ui-blocks 页面块与元素 chip

前言

在 DeepSeek Harness(DSH)里做界面原型或 UI 说明时,常见做法是把 HTML 贴在消息里当普通代码块,模型和用户都只能「看文本」,无法在聊天流里按固定视口预览布局,也很难把画布上某个按钮、卡片精确指回输入框。维护者 YukimuraSol 的客户端插件 dsh-ui-block 针对这类需求:在消息里用一行指令引用 ui-blocks/ 下的 .uiblock 文件,在沙箱 iframe 里按声明分辨率渲染;并在画布内点选 DOM,把 element«…» token 作为 chip 写进 composer,序列化仍回到原文 token。

下面介绍插件定位、已文档化的能力、安装方式与典型写法。功能与语法以仓库 README 为准;社区目录 SkillHub 与 GitHub 同源,与 DeepSeek / 幻方无官方从属关系。

这是什么

dsh-ui-block 是 DSH 的 web 客户端插件(package.json 中 dsh.client.platform: web,immediately: true),通过 Cordis bundle patch 注入聊天与会话 UI 依赖。一句话:解析消息中独立一行的 ::dsh-ui <name> [res=WxH]::,读取 ui-blocks/<name>.uiblock,在消息流里用与宿主一致的 CodeBlock 外壳挂载沙箱画布;选区模式下选中元素时,经 conversation.input.overlay 把 element token 插入输入区,渲染与复制行为复用 dsh-element-chip 的 source: 'element' 路径。

当前 npm 包版本为 v0.2.2(MIT)。仓库:https://github.com/YukimuraSol/dsh-ui-block。

触发方式与文件引用(2026-10-24 起)

2026-10-24 起,触发方式改为消息里单独一行(前后可有空白,不带反引号、不在围栏里、不带别的字):

::dsh-ui 名字::

或指定画布逻辑分辨率(宽×高):

::dsh-ui 名字 res=820x510::

该行在界面上会被隐藏,画布插入在原位置。res= 决定 iframe 的 CSS 视口,缺省为 1440×900。横栏语言标签固定为 dsh-ui;复制按钮复制的是路径 ui-blocks/<name>.uiblock(code 传路径,<pre> 仅作隐藏)。

旧写法(裸围栏 + 块体首行 dsh-ui ref: ui-blocks/<name>.uiblock)已从代码中删除,无兜底识别。若仍在用围栏首行 dsh-ui res=… 内联 HTML 的旧 meta 行,且没有 dsh-ui 前缀的迁移形态,将不再渲染,控制台会出现 missing-dsh-ui-prefix 类诊断。

核心功能

沙箱画布与尺寸模型

插件把每个块当作「看画布的窗户」:

  1. 画布分辨率(res=):改 iframe 真实视口,内容会重新排版,media query 生效。非法或缺失的 res 回退 1440×900,整块仍渲染,不退回普通代码块。
  2. 缩放:光标在画布上滚轮,以光标点为中心缩放(约 20%–400%),仅 transform,不重排;双击画布可复位为适应宽度。
  3. 外框高度:默认 min(画布高×初始适应, 480px);历史文档中的 h= 等围栏 meta 随旧触发方式退役,当前以横栏与拖曳下缘把手(约 120px–视口高)调整为主。

画布大于窗格时可拖拽平移;iframe 自身 pointer-events: none,交互由插件透明层接管。缩放、选区、读文件与报错处理在 README 变更说明中标注为与早期实现一致的部分未改。

按消息时刻还原(2026-10-25)

引用语法不变,仍是一行 ::dsh-ui <name>:: / ::dsh-ui <name> res=WxH::。一条消息里显示的块内容是该消息首次渲染时的版本;之后修改 .uiblock 只影响之后的新消息。钉住状态在宿主侧 ui-blocks/.pins.json,刷新后各消息仍各显示各的版本。

历史存于 ui-blocks/.history/<名字>/:首次见到的基线 base.uiblock,log.json 每行 {at, patch} 行级补丁。宿主可通过查询参数还原:?at=<epoch毫秒> 取某一时刻内容;?pin=<对话节点键>&i=<第几条> 首次请求钉住「现在」后沿用;都不带则显示最新(兼容旧客户端)。钉住后的引用不再周期性重读文件。找不到 [data-chat-node-key] 祖先时(如草稿预览)退回不带 pin、显示最新。

注意:升级前已存在的历史消息在首次渲染时才钉住,钉的是当时的「现在」,无法 retroactive 还原更早版本——README 明确说明这是信息缺失,补不回来。

画布内选区(v0.4.0)

横栏分辨率控件右侧有选区按钮(13×13 SVG,无文字)。点亮后可在画布内:

  • 移动鼠标高亮元素;滚轮在层叠栈中切换(不触发缩放);
  • ↑↓←→ 在父子、兄弟间导航(焦点需在 iframe 内);
  • 点击确认选中,token 直接插入 composer(不经剪贴板);
  • 再点一次图标退出;Enter / Esc 不绑定。

同页仅一个块可处于选区 armed 状态。token 为三行 element«…» 格式(DOM Path、Position、HTML Element),规则与 element-picker 对齐;插入走 slash/input-insert-reference,source 为 'element' 以复用 chip 实现。座位 id 为 dsh-ui-block-picker,与 dsh-element-chip 的 overlay 座位 additive 共存。

自检

仓库提供:

node self-check-uiblock-directive.mjs

README 称当前约 46 条断言,覆盖新指令解析、旧写法不命中、代码块内不命中、非法 res、补丁链与 pin 还原等。

安装与启用

DSH 生态按「一切皆插件」扩展;安装方式以你在用的 Harness 与社区目录为准,不要在未核对文档的情况下自行拼接未出现的 CLI。

SkillHub 目录页 给出的 Harness 安装表述为:

请安装 DSH 插件 YukimuraSol/dsh-ui-block。

安装前建议在 GitHub 阅读 README.md、cordis.patch.yml 与 client.js 入口行为,确认与当前 DSH 客户端版本匹配。插件标记为可安装客户端,启用后会在 web 端立即注入(immediately: true)。

典型用法

1. 准备 ui-blocks 文件

在宿主约定的 ui-blocks/ 目录下放置与名字对应的文件,例如 ui-blocks/login-modal.uiblock(内容为要在沙箱中渲染的 HTML/CSS/JS,以你项目实际约定为准)。

2. 在消息中引用

发送单独一行(示例名与分辨率可按需替换):

::dsh-ui login-modal::

需要更窄的预览视口时:

::dsh-ui login-modal res=820x510::

3. 从画布指回输入框

点亮选区按钮,在画布内选中目标元素,确认后 composer 会出现 element chip;复制或发送时仍序列化为完整 element«…» token,便于模型定位 DOM。

4. 开发与回归

改插件或块文件后,可在仓库根目录运行 node self-check-uiblock-directive.mjs 做指令与还原逻辑自检。

适用场景与注意

适合:需要在对话流中预览 ui-blocks 静态/轻交互原型;希望用与浏览器选区一致的方式把具体节点引用进下一轮 prompt;与 dsh-element-chip 共用 token 格式的 UI 协作流。

注意:

  1. 插件在 当前 DSH 进程权限 下运行,能读写的路径以 Harness 与插件实现为准;安装前请审查源码与 MIT 许可证。
  2. 触发行必须满足「单独一行、无反引号、无围栏」;写在普通代码块里的 ::dsh-ui …:: 不会命中。
  3. 消息级 pin 与补丁链依赖宿主侧 ui-blocks/.pins.json 与 .history/;备份或迁移工作区时需一并考虑。
  4. README 中关于双 profile(如 3080 / 4000)junction 的说明面向插件开发者同步副本,普通使用者以单一安装路径为准即可。

结尾

dsh-ui-block 把「一行引用 + 外部 .uiblock 文件」变成聊天里的沙箱预览,并把画布选区接进 composer chip,减少在 HTML 字符串与真实布局之间来回对照的成本。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜