Files
Yichen Jiang 56d3e8f82a fix(agent-presets): answer health from the walk alone, and keep the reason reachable
`import.meta.resolve`'s `parentURL` argument takes effect only under
`--experimental-import-meta-resolve`, which no launch passes, so the
fallback resolved from this module rather than from the harness — the one
question it existed to answer. The disk walk is the whole answer now, and
the refusal memo it needed goes with it. A `file:` URL joins the file
branch rather than the package one, where a resolver would only normalize
it and report a missing target as present, and a row is skipped on the
Loader's own `Boolean(disabled)` so `disabled: 0` is checked like the
Loader checks it.

A broken card says so through `aria-disabled` rather than `disabled`, and
refuses the pick in its own handler. `disabled` took it out of the tab
order, which with the reason moved onto the badge left it unreachable
without a pointer — reachable before this change, so hiding it was a
regression rather than a path that never existed.

Both notes this decision partly supersedes are updated in place and
cross-linked, one README pair loses an editing residue that repeated a
sentence, and the single-row diagnostic no longer reads "row row 1".
2026-08-26 14:42:39 +08:00

8.6 KiB

description, kind
description kind
dsh Web 客户端共享的 React UI 原子组件:控件、图标、Markdown 与数学公式渲染,以及终端/读取/差异/搜索/网页输出卡片(零 cordis)。 package-library

@deepseek-ai/dsh-client-ui-primitives

English | 中文

概述

dsh-client-ui-primitives 是 Web 客户端共享的 React 组件库:每个功能插件都用这些原子组件拼装自己的 UI,而这里没有任何内容依赖 Cordis 或 slot 系统。它提供控件集(按钮、胶囊、输入框、菜单、模态框、Toast 横幅、折叠行、悬浮卡片、连接横幅)、图标字形与品牌标记、锚定浮层用的定位钩子,以及 agent 输出的内容渲染器:带 TeX 公式的 markdown、终端输出、文件读取、差异、搜索结果、网页检索与 JSON 检查。这些渲染器为不受信任的模型输出而设计——原始 HTML 会被丢弃、链接会被失效或安全打开、ANSI 转义序列会被解析而非透传。面向用户的文案通过 label prop 提供;拼装某个原子组件的功能插件负责本地化。

目录


使用本包

只要 Web 客户端需要标准控件或 agent 输出渲染器,就用这些原子组件拼装功能 UI。它们只经 React 渲染,并从主题取得 --dsw-* 设计 token,因此无需导入主题或 slot 系统即可适配任意插件。

控件与图标

ButtonPillInputMenuModalTooltipDisclosureRowStateDotHoverCardToastConnectionBannerRiskConfirmation 与首次运行接管层 OnboardingSurface 覆盖常见的交互形态。ic_ds_* 图标集与 FishLogo/BrandWordmark 标记填充品牌与行内图标 slot。useAnchoredPositionuseAnchoredMaxHeight 让浮动面板与底部锚定浮层始终钳制在视口内并跟随锚点。HoverCard 通过指针离开宽限期让采用 portal 的预览在跨过锚点间隙时仍可触及,并可通过 copyText prop 提供复制按钮。 Toast 的停留时长由使用方通过 holdMs 指定,因为横幅该留多久取决于有多少内容要读;同一个值同时驱动它的卸载定时器与样式表的淡出延迟,两者不可能再错位。

渲染 agent 输出

MarkdownText 渲染不可信的 GFM 与 TeX 公式、阻止不安全的链接与图片,并可把已解析的文件提及转换为显式控件。回复流式输出时,它冻结已完成的块,并从保存的 Shiki grammar state 为不断增长的 fence 增量高亮;最终渲染使用相同的 span 树(增量渲染器流式 fence 高亮)。TerminalBlockReadBlockDiffBlockSearchBlockWebBlock 把对应的工具结果意图渲染为带复制控件、溢出处理及适用时 ANSI 处理的卡片。JsonTreeJsonBlock 以只读方式检查 JSON 值;MessageText 仍是用户创作内容的字面文本原语。

本地化文案

这些原子组件无法读取应用 locale,因此每段面向用户的文案都必须通过 label prop 提供。HoverCardTerminalBlockJsonTreeCodeBlockMarkdownTextJsonBlockConnectionBannerModalDiffBlockReadBlockSearchBlockWebBlock 接收完整的本地化 label。本包不拥有语言回退;遗漏会导致类型检查失败,各功能会把带类型的 t 席位映射到 primitive 的 label 接口。


理解实现

实现细节——点击展开

本包只做一件事:提供零 cordis、零 slot 知识、仅经 --dsw-* token 设置样式的纯 React 原子组件,而所有功能专属的关注点(locale、会话数据、组合)都留在拼装它们的插件中。

源码地图

文件 职责
src/index.ts 原子组件公开导出
src/markdown/ Markdown 与数学公式流水线:micromark 解析、KaTeX 排版、增量流式渲染器、CodeBlock/JsonBlock
src/TerminalBlock.tsx ANSI 转义解析(anser)与终端卡片渲染
src/ReadBlock.tsx / src/DiffBlock.tsx 读取与差异卡片
src/SearchBlock.tsx / src/WebBlock.tsx 搜索与网页检索卡片
src/icons/ ic_ds_* 字形组件与品牌标记
src/useAnchoredPosition.ts / src/useAnchoredMaxHeight.ts 浮动面板与浮层几何钩子

流式 markdown

回复流式输出期间,MarkdownText 增量解析:除末尾两个块外全部冻结为缓存的 React 元素,每个分片只重新解析其后的源文本尾部,因此每分片的工作量跟随尾部而非整个回复。不断增长的 fenced block 会从已保存的 Shiki grammar state 加上尚未完成的最后一行继续分词;已完成行保留其 DOM,定稿渲染则使用相同的 span 树。定稿时的全量解析还会解析跨过冻结边界的引用(增量渲染器流式 fence 高亮)。

几何与溢出

输出卡片共享同一套几何模型:white-space: pre 并横向滚动,让按列对齐的内容保持对齐;超过 maxLines(默认 16)时折叠为头部切片加尾部切片,由展开按钮控制,长正文不会撑高卡片。TerminalBlock 把 ANSI 解析为 React span,并带逐行列缓冲处理光标移动,遵循行内擦除、制表位与字符宽度。


进一步探索

以下页面说明这些原子组件在客户端技术栈与设计系统中的位置。

  • ui-renderer——挂载组装后应用并绑定 slot 数据的 React 渲染器。
  • ui-tool——拼装这些输出卡片的工具调用展示层。
  • ui-conversation——渲染 markdown 回复与工具卡片的聊天界面。
  • ui-theme——这些原子组件样式所依赖的 --dsw-* token 体系。
  • Web 样式——Web 客户端组件的权威样式规则。

模型体验

无。该包是浏览器端 UI 插件层,不注册任何面向模型的内容。

KV Cache 影响

无;该包既不组装也不发送提供方请求。

已知限制与延期工作

这些限制说明原子组件在边缘情况下的行为;它们是当前包约束,不是组件路线图。

  • 流式期间跨边界引用解析被推迟:定义落在增量冻结边界另一侧的引用式链接或脚注,在回复流式输出期间渲染为字面文本;定稿时的全量解析会将其解析。
  • 字形级图标是重新绘制的近似版本:鱼形标志与闪光标记来自字体字形,而本地设计数据无法导出其矢量几何;在获得精确导出路径前,使用手工重建版本代替。
  • PillInput 没有设计来源:两个原子组件均自行定义;与其相似的侧边栏搜索字段和视图标签条由消费方组合,不是这些原子组件。
  • StateDot 没有 Active 变体:支持的状态为 done、warning、ongoing 和 error。
  • 面向用户的文案必须由渲染点提供:这些原子组件是 zero-Cordis 的,拿不到 ctx.locale;各功能必须通过 primitive 的带类型 prop 提供完整本地化 label(见决策)。
  • TerminalBlock 不是终端模拟器:它渲染已结束或仍在运行的命令输出,而不是交互式会话:SGR 颜色、回车、退格、行内擦除、制表位与字符宽度会被遵循;绝对光标定位、清屏与备用屏幕序列会被剥离。

开发备注

维护者的工作上下文——点击展开

无。