DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-viewer-kit

h

dsh-viewer-kit

Manifest valid

A plugin that enhances the display of deepseek harness session content

UI (client)hasBundlePatchMachine translated

dsh-viewer-kit

给 DeepSeek Harness(dsh)对话窗口用的 可插拔内容渲染层:让代码块除了「源码」之外还能有「渲染结果」,两者一键切换。

这是一个 vibe coding 项目。 代码绝大部分由 AI 在对话中生成,作者负责提需求、验证结果、 以及在它跑偏时把方向纠回来。它能工作、有测试,但依赖前请先读代码 —— 不要假设它有常规开源项目的打磨程度。版本号 < 1.0,配置键不保证稳定。


1. 功能与配置

它做什么

围栏切换渲染结果是怎么来的
html svg预览 / 代码沙箱 iframe 真实渲染,默认禁脚本;可放大成弹窗看全文
csv tsv表格 / 代码自己实现 RFC 4180 解析,DOM 建表(不解析标记);表头吸顶
json表格 / 代码只认对象数组;对象不是表
markdown表格 / 代码只认整个围栏就是一张管道表,否则原样
echarts chart图表 / 代码模型只写 option 的 JSON,引擎按需加载
其它(py …)—完全不碰,DSH 什么样就什么样

只作用于「会话」标签页。 轨迹标签页也渲染 .md-code-block,但它的 DOM 不带任何 data-chat-* 属性而会话区带 —— 边界建在这个实测差异上,不需要知道 shell 如何组织标签页。

echarts 围栏不需要写 HTML。 只写 ECharts 的 option JSON 就够了,不用引 CDN、 不用 <script>、也不需要打开 htmlAllowScripts —— 引擎是插件自己按需加载的代码。

原型模式:一次性注入风格规范

当你说「把这段沟通内容做成 HTML 原型」时,模型会调用一个工具 apply_prototype_style。 紧接着的那一次请求里会被注入一段固定的风格规范(默认是 Mockplus 式低保真: 黑白灰、无阴影、无外部 CSS 框架、样式集中在一个 <style> 块),模型照着输出原型。

注入一次就自动失效,后续正常对话完全不受影响;下次要原型时再触发一次。

状态的生命周期由提示词组装器管,不由模型管:模型只负责触发,没有任何"关闭"的动作 可用。所以即使模型"忘了关",约束也只生效一轮。

默认规范是英文的。 它是喂给模型的提示词,不是给你读的配置项。想要中文规范 (或者你们团队自己的配色、栅格、组件约定),用 prototypeStyle 配置项整体替换。

默认注入的规范原文:

# Low-fidelity HTML prototype style

These rules apply to the HTML you emit in THIS response only. They expire
immediately after it; ordinary conversation is unaffected.

## Colour
Greyscale only: #333 body text, #666 secondary text, #999 placeholder or
disabled text, #ccc borders and dividers, #eee background fills.
No colour of any kind, no gradient, no shadow.

## Type
font-family: system-ui, -apple-system, sans-serif

## Controls
Buttons and inputs: border 1px solid #ccc; border-radius 4px; box-shadow none.
Cards: border 1px solid #ddd; border-radius 4px; box-shadow none.

## Forbidden
- External CSS frameworks (Tailwind, Bootstrap, Ant Design, and the like).
- Gradients, box-shadows, animations, transitions.
- Icon libraries and icon fonts. Use plain text or a minimal CSS shape.

## Structure
Every style lives in ONE <style> block. No inline style attributes.

This is a wireframe, not a visual design: get hierarchy and layout right,
and do not spend effort on polish.

实际效果

以下截图取自 DSH Desktop 0.2.0-rc.2 真实运行,未做修饰。

html —— 沙箱 iframe 渲染,高度贴合内容:

HTML 预览:沙箱渲染,高度贴合内容

html · 放大 —— 点右上角图标,同一个文档进弹窗,按视口高度铺开:

HTML 预览:放大成弹窗

echarts —— 模型只写 option 的 JSON,引擎作为独立文件按需加载:

ECharts 图表:柱状 + 折线双系列

csv —— 自实现 RFC 4180:引号内的逗号与转义引号不会被拆成两格:

CSV:引号内逗号与转义引号

json —— 只认对象数组:

JSON 对象数组渲染为表格

markdown —— 只认整张管道表:

Markdown 管道表渲染为表格

高度与「看全内容」

三个渲染器里只有两个物理上必须封顶,因为它们的内容高度无法从 DOM 推出:

渲染器封顶为什么必须
htmlmaxPreviewHeight 320<iframe> 是替换元素,高度永不来自内部文档;max-height 只能限制默认的 150px。只能测出来再封顶
echartschartHeight 360canvas 在 auto 高度盒子里渲染成 0 高
tablemaxTableHeight 480不是必须 —— 表格能自然撑开。封顶是为了不把对话拉长

封顶和逃生口是成对的:只封顶不给出路,等于拿掉"一眼看全 500 行"的能力, 而那恰恰是没封顶时唯一能看到全部的方式。所以被认领的块会带一个放大图标 (与 banner 里 DSH 自己的复制按钮同款):

  • 表格 —— 就地取消高度封顶,整张表在对话里展开。再点一次恢复。 表格比 maxTableHeight 矮时不会出现这个按钮:那种表格本来就没被裁,取消封顶一个像素都不会变。
  • HTML 预览 —— 开一个弹窗,高度按视口的 86% 算,内容按真实高度撑开。 短文档无滚动条、无留白;长文档只在物理上装不下时才出现滚动条。

图表没有放大控件 —— 它有确定的 chartHeight,不存在"内容比框高"那种失控。

配置

所有可调项都是插件配置,写在 Loader 行的 config 里。改当前 profile 的行为:

# $DSH_HOME/profiles/<name>/cordis.patch.yml
- id: dsh-viewer-kit
  config:
    htmlAllowScripts: true

用户 patch 在所有组合包层之后应用、按行 id 胜出,所以这样写会覆盖包内默认值。

改完要重启 profile,不只是刷新页面。 配置由宿主半体在激活时读取并校验, 浏览器是启动后去取它的结果;刷新页面只会让客户端重新拉一次同样的结果。 宿主进程日志里 host config published at /dsh-viewer-kit/config: {...} 就是它读到的值。

键默认作用
enabledtrue总开关。false 后所有渲染器都不认领,代码块保持 DSH 原样
defaultToPreviewtrue认领到的块默认打开渲染结果而不是源码
previewHeightModemeasureHTML 预览高度怎么定 —— 见下
maxPreviewHeight320measure/fit 下是上限,fixed 下就是框高
maxTableHeight480表格超过这个高度就开始框内滚动,表头吸顶
chartHeight360图表高度。必须 > 0,否则画布渲染成 0 高
htmlAllowScriptsfalse允许预览里的 HTML 执行它自己的脚本
maxSourceBytes262144超过这个大小的源码保持原生代码块
disabledRendererIds[]关掉个别渲染器,两层语义 —— 见下
prototypeStyle""替换原型模式注入的风格规范;空串 = 用内置的那份 —— 见上

值写错了会怎样:宿主半体响亮报错并拒绝这一行,而客户端半体静默回落默认值。 两边的严格程度故意不同,理由和排查顺序见 AGENTS.md §1。

预览高度是怎么定的

模式短内容长内容代价
measure(默认)框贴合内容,无留白顶到上限后框内滚动frame 需要 allow-scripts 跑测量脚本
fit估算贴合,可能略差同上估算偏小时会出现滚动条
fixed完整显示,下方留白到固定高度超过即滚动完全可预期,但短内容必然有留白

为什么默认是 measure: DSH 自己的代码视图也没有固定高度(<pre> 只设了 padding 与 overflow-x:auto,高度由内容决定)。固定预览高度会让两个互相切换的视图行为不一致; 测量让预览和它旁边的代码视图保持同一种语义:内容多高就多高。

disabledRendererIds 的两层语义

同一个列表,两层,这是它容易搞错的原因:

写法含义块会怎样
['table']按渲染器 id 关闭该渲染器不再认领,块重新交给剩下的渲染器;没人认领就回落原生代码视图
['csv']按围栏名关闭该块根本不进渲染器,不管有没有渲染器认领它

两者会重叠:['csv'] 和 ['table'] 都能关掉 CSV 表格,但原因不同。真正分家的是 没有同名渲染器的语言 —— ['json'] 会让所有 json 块原样保留,而这是"别让 ECharts option 被表格渲染器认领"却不点名 echarts 的唯一办法。

关于 htmlAllowScripts

默认关闭,所以预览里带 <script> 的 HTML 不会执行。这和 echarts 图表无关 —— 图表走 ```echarts 围栏,引擎是插件按需加载的可信代码。

打开后 frame 仍是不透明源,读不到宿主的 DOM / cookie / storage。变化的是: 仅仅渲染一段内容就可能发起该内容里的网络请求(远程图片自动加载、脚本可向任意地址发请求)。 内容本身是模型写的,泄露面基本限于模型已写出的东西 —— 但"看一眼就联网"确实是新引入的能力。

DSH 没有「按 schema 自动生成表单」这回事。 本插件导出 Config schema 得到的是 校验 + 默认值 + agent 可读的 JSON Schema,不是一个能点的设置界面。 所以配置就是上面那段 patch 文本。

已知限制

  1. 强耦合 DSH 的内部 DOM。 插件不注册 Slot、不重写组件,而是在 DSH 的 [data-code-block-content] 旁边挂自己的节点 —— 那节点是官方 CSS 注释标注的 "stable content node",但它依然是内部实现。核对版本:DSH Desktop 0.2.0-rc.2。 DSH 升级后形状一旦改变,插件会静默不生效(不是崩溃)。核对入口只有一个文件: src/client/dom-contract.js,升级步骤见 §3。

  2. 围栏语言名可能是空的。 DSH 的语言表是 Shiki 内置的,不支持自定义, banner 只在有高亮器时才写语言名。所以 ```echarts 拿到的标签是通用文案, 原始语言名在 DOM 里不存在。插件的应对是按内容判定。

  3. 只有会话页。 轨迹页的代码块不会被动。

  4. 行数列数有上限(500 行 × 40 列,单元格 400 字),超出部分截断并提示。


2. 安装

# A. 从本地目录(开发时最常用)
dsh plugin add file:E:\path\to\dsh-viewer-kit

# B. 从 tarball(适合分发给别人 / 内网)
npm pack                       # 产出 dsh-viewer-kit-0.9.0.tgz
dsh plugin add file:.\dsh-viewer-kit-0.9.0.tgz

装好后重启 profile,让宿主半体生效。

不要走 github: 直装。 官方《打包与安装插件》 明确警告:git 安装拉的是源码不是产物,pnpm ≥10 会拒绝运行它的 prepare 脚本, 除非用户在 profile 的 pnpm-workspace.yaml 里写 allowBuilds —— 那等于允许该包的代码 在安装时于本机执行、且不在任何沙箱内。分发预构建产物就没有这道坎。

确认它活着

浏览器控制台出现四行(宿主进程另有一行 host config published at …):

[dsh-viewer-kit] renderers: html, echarts, table
[dsh-viewer-kit] waiting for the host config route
[dsh-viewer-kit] config: default view=preview, html scripts=off, max preview height=320px, chart height=360px (from defaults, host answered 404)
[dsh-viewer-kit] v0.9.0 active — N code block(s) enhanced

渲染器按优先级排列而非注册顺序:html 10 > echarts 8 > table 5。 括号里是配置的来源。from host 说明宿主半体在跑、cordis.patch.yml 里的值已生效; from defaults, … 说明没读到宿主配置,所有键都是默认值 —— 原因写在括号里。

排障时用这一条命令:

__DSH_VIEWER_KIT__.diagnose()

它区分三种"装了但没渲染":客户端半体没加载(__DSH_VIEWER_KIT__ 为 undefined)、 接缝没找到代码块、找到了但没有渲染器认领。


3. 开发

改动本仓库请看 AGENTS.md —— 命令、架构不变量、单一真相来源、 房子规矩、升级 DSH 的步骤都在那里。README 只留使用者需要的东西。

pnpm install
pnpm run check        # 类型检查 → 构建 → 161 项测试 → 产物激活复现 → 宿主契约探针
pnpm run release      # check + 打包自检,完整发布门禁

需要 Node ≥ 22(tsdown 用到 Promise.withResolvers),而且要用版本管理器显式选定 —— pnpm run 是用 PATH 上的 node 拉起子进程的,PATH 上是旧版会直接失败且报错指向 tsdown:

fnm exec --using=24 -- pnpm run check

改完要重新构建再提交:client/ 是提交进库的产物(DSH 激活时会直接读这个文件, 缺了它 entry 就激活失败)。


4. 其他

安全

模型产出的 HTML 属于不可信输入。预览一律走 <iframe sandbox>:

  • 任何配置下都不会同时给 allow-scripts 和 allow-same-origin(那才是真正的逃逸);
  • measure 模式的 frame 带 allow-scripts(跑测量脚本),模型脚本由 CSP nonce 策略 拒绝;fit / fixed 模式下 frame 是 sandbox="",零脚本权限;
  • referrerpolicy="no-referrer";
  • 表格视图用 DOM API 建节点,不解析模型产出的标记;
  • 不提供"在新标签页打开"—— 那会用 blob: URL 以宿主同源执行,恰好绕开全部沙箱保证。

已知的残留风险:渲染一段 HTML 可以发起该内容里的网络请求(远程图片、CSS), 这一条在所有配置下都成立,因为浏览器必须加载子资源才能排版。

它是怎么工作的

不注册任何 Slot、不重写任何组件,只在 DSH 自己标注为 "stable content node" 的节点上 追加我们自己的节点;切换视图只改一个我们自己的属性,原生 <pre> 一个字节都没动过。 架构与取舍的完整记录在 docs/01-architecture.md, 新增渲染器见 docs/02-renderer-authoring.md。

升级 DSH 之后

  1. 核对 src/client/dom-contract.js 里引用的 DOM 形状 —— 只有这一个文件需要改;
  2. pnpm run check:类型检查、夹具与断言会告诉你变了什么;
  3. 重新构建并拷贝覆盖(步骤见 AGENTS.md §3)。

许可

MIT

Comments

Loading…

Similar plugins

dsh-viewtune

by Farewish

DeepSeek Harness 的视效+小功能改进插件

Manifest valid

★ 0

JavaScript

Oct 1, 2026

dsh plugin --profile web add dsh-viewtune

by rangdl

DSH(DeepSeek Harness)功能增强插件

Development & InfrastructureManifest valid

★ 0

TypeScript

Sep 1, 2026

dsh plugin --profile web add dsh-all-enhance

by PwnKY

DeepSeek Harness 的 Codex 式会话深度链接插件:dsh:// 深链,跨对话读取上下文

Sessions & MessagesManifest valid

★ 7

↓ 350/wk

MIT

JavaScript

Sep 24, 2026

dsh plugin --profile web add dsh-session-link

by Skylarking

DeepSeek Harness plugin: chat renderer

Manifest valid

★ 0

TypeScript

Aug 20, 2026

dsh plugin --profile web add @skylarking/dsh-chat-renderer

by drscrewdriver

给 DeepSeek Harness 侧边栏加一个会话内容检索——标题/内容一键切换,还能按用户/回复/工具筛选

Sessions & MessagesTerminal & ClientsManifest valid

★ 4

↓ 24/wk

MIT

TypeScript

Oct 6, 2026

dsh plugin --profile web add dsh-session-search-toggle

by donyue7

DSH(DeepSeek Harness)插件:在会话视图标签中展示项目的 AOCI 认知索引、治理状态与条目浏览

Development & InfrastructureTerminal & ClientsManifest valid

★ 0

MIT

JavaScript

Sep 23, 2026

dsh plugin --profile web add dsh-aoci-panel