DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

Viewtune — DSH Plugin for DeepSeek Harness
← Plugins
V

dsh-viewtune

Viewtune

A calmer reading view for DeepSeek Harness: native process details, live reasoning, and clean final answers. (Relayout fork of aa2246740/dsh-better-display: framed short reasoning, native-scroll reasoning card with edge handoff, all user/context messages above the process disclosure.)

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:Farewish/dsh-viewtune#ab48dc40595a70a4c1de713979a7b3ab066fca48
READMECompatibilityVersions

Compatibility and provenance

Viewtune is published as dsh-viewtune and currently resolves to version 0.4.1. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
github
Registry updated
9/24/2026

Versions

0.4.1stable
9/24/2026
0.4.0stable
9/23/2026
Show 2 more versionsCollapse versions
0.3.0-relayout.14prerelease
9/19/2026
0.3.0-relayout.13prerelease
9/18/2026

Related plugins

Loading related plugins…

Latest
0.4.1
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
MIT
Source
github
GitHub
★ 0
Weekly downloads
0
Last push
9/24/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in

Related plugins

More verified plugins in ui-customization.

Web App@deepseek-ai/dsh-web-appThe dsh browser-surface bundle: the web patch layer over dsh-base plus the runtime glue plugin (frontend dist serving, web-surface prompt, bash runtime variables, URL line)Experimental Agent Team Web Profile@deepseek-ai/dsh-experimental-agent-team-web-profileExperimental Web profile layer for Agent Teams Remote and UI pluginsRemote Web Ui@linxin666/dsh-remote-web-uiScan-to-pair remote access for the dsh web GUI that shares one official interface: a QR beside the settings button pairs phones and PCs into the same Web GUI (a portrait-touch adaptation layer for phones, full desktop on PCs) through one-time tokens and rClient Ui Git Graph@linxin666/dsh-client-ui-git-graphExternal dsh web GUI plugin: a blank-session git branch selector + Git graph, with real host-side git operations and guards, as a dsh profile bundle

README

dsh-viewtune

English

给 DeepSeek Harness 的阅读页签:一轮对话在进行时过程是看得见的——思考在写、工具在跑、到了第几步;一轮成功结束后过程收起来,只留最终回答。在此之上是一层可调的皮:一张壁纸、一层磨砂玻璃,以及一个把设置放在阅读页签里的面板。

上游原版的「对话 / 轨迹」页签、输入框、模型选择、工具与审批全部保留,本插件只增加一个阅读视图。

面向 DeepSeek Harness 0.1.5-rc.2。只改展示,不碰 Agent 执行、SDK 或模型凭据。Node.js ^22.19.0 || >=24。

安装

需要 PATH 上有官方 dsh(没有就用 npx @deepseek-ai/dsh)与 pnpm —— dsh plugin add 会在 $DSH_HOME/profiles/web 里跑 pnpm。

# 从 GitHub 安装
dsh plugin --profile web add github:Farewish/dsh-viewtune

# 或从本地目录 / tarball 安装
dsh plugin --profile web add ./dsh-viewtune
dsh plugin --profile web add ./dsh-viewtune-0.4.1.tgz

装完重启 Host 再刷新页面:dsh plugin add 只写 profile,不会热挂正在运行的进程。

卸载:

dsh plugin --profile web remove dsh-viewtune

三点容易踩的:

  • dsh.bundle 是开机捕获的,不要再往 profile 的 cordis.patch.yml 手写同一条 insert,会重复挂载。
  • 本仓库已提交编译好的 lib/,安装时不需要 prepare,也不需要给 profile 加 allowBuilds。
  • 与上游 dsh-better-display 不要同时安装:两者的 bundle 补丁插入同一个入口 id,同时挂着会重复挂载。用上面的 remove 卸掉本插件后,再装回上游才是干净的。

一轮长什么样

一个「对话」在这里是一轮(提问 + 回复),阅读视图按这个单位组织:

  • 过程可见:思考、工具调用、子代理与进度实时呈现,长轮次不会只剩一个转圈;一轮成功结束时过程自动折起、只留回答,运行中或未完成的轮次保持展开。

  • 用户消息都在最前:一轮里可能以系统提示词开头并携带多条 user / steering 消息,它们按源顺序全部渲染在过程折叠开关之前。带与不带系统提示词的对话,顺序一致:

    用户的话 → 折叠开关(用时 X 秒,可点击)→ 流程(系统提示词 / 思考卡 / 工具 / 回答正文)
    
  • 短思考与长思考同框:不再因为「没有溢出」就取消边框,短思考的标题与正文内边距与长思考一致。

  • 等待时钟:模型正在思考或输出时,状态行右边显示「这一轮交给模型多久了」。前 3 秒完全不显示(等待通常比这更短,数字一冒出来只会把眼睛拉过去),过十秒挂一个「暂未响应」。锚点是最后一次交棒(工具返回、上下文注入、命令结束、你刚发言),不是轮次开始;工具还在跑时不计时——那时忙的是工具,不是模型。

  • 步骤胶囊:回答末尾的动作行里显示该轮回答落在第几步 / 全轮共几步,点开是中文的过程记录,不是原始 JSON。

  • 改动行计数:改了文件的工具行尾部显示 +N -M(增绿删红),点开是按文件分页的差异面板。计数优先读宿主已附在结果里的 meta.diffs,没有才退回调用参数——而且只对真正会改文件的三种工具这么做(好几个不相干的工具都有叫 content 的字段);子调用改的文件也算在这一行里。

  • 交互式 mcp-app 卡片:回答里的 ````mcp-app代码块挂成交互卡片,跑在内、**没有**allow-same-origin;卡片可通过 JSON-RPC 把下一轮 prompt 填进输入框。技能包见 [skills/generative-mcpapps/`](skills/generative-mcpapps/)。

  • 思考区的滚轮交给浏览器:卡片内原生滚动,滚到底后整格原生上链到会话。跨过底边那一格、卡片吃不下的余量会被丢掉(最多一格,一个手势只发生一次)——这是「一格都不从浏览器手里拿走」的代价;没有溢出的短思考完全不拦截滚轮。

工具栏与「收起」

  • 一条吸顶泳道:「收起」+「viewtune ⚙」在阅读视图顶部,横跨整个阅读视图——分隔线与宿主的顶部栏一样从一头到另一头,而两个控件仍停在文字左边缘;它吸顶在顶部栏正下方,属于外层的横条而不是浮在内容上的东西,所以滚到任何深度都够得到。
  • 一个控件,三个模式:收起与全部收起合并成一个按钮(阅读列左边缘只放得下一个控件)。两条条件都成立时,主按钮收起你正在看的这一轮、旁边的双箭头一次收完全部(title 与可访问名逐字就是「全部收起」);只有一条成立时按钮就是那个动作,没有箭头。设置里可以把它钉成单动作。
  • 作用域只有当前这一轮:判定方式与阅读滚动选锚点用的是同一条谓词,视口横跨两轮时取上面那一轮。
  • 快捷键 Alt+C / Alt+Shift+C,可在设置里改。收起之后如果按钮本身消失了,焦点会回到工具栏的另一个控件而不是页面 <body>。

设置面板

点「viewtune ⚙」打开,分三页(键盘用方向键 / Home / End 在页间切换):

  • 视效:动效(被系统的「减少动态效果」覆盖时会写在行里说明)、磨砂玻璃、九个旋钮、壁纸。
  • 功能:这个插件对 App 做了什么,分三组(组间一条分隔线):小功能——竖条滚轮、产物用右侧栏打开、自动收起更早流程;正文显示——逐词显现、逐词显现的模糊、正文更新节奏;流程展示设置——跟随到最新、思考卡自动跟随、自动滚动速度、焦点思考展开。只在别的设置下才有意义的项(模糊、速度)缩进排在它下面,并在不适用时置灰。
  • 快捷键:收起按钮的行为,以及本插件自己那两个绑定的录制(点键帽录制,Esc 取消,清除即不带快捷键;没有修饰键或已被浏览器占用的组合会被拒绝)。

一条排版约定:加一个偏好就是加一行、加一类就是加一页,工具栏不会因此变宽;只有标签说不清的选项才带说明,那句说明挂在该行的 title 上(浏览器弹的原生框,和按钮、「收起」是同一套),平时不占版面。而被系统覆盖、录制中、组合被拒这类状态直接写在行里。

设置的出厂值就是本插件默认的那一套(见下:皮肤开着、壁纸是自带那张、铺满整窗、正文节奏固定 60 次/秒)。老记录里只保存读者改过的键,缺的键用出厂值。

磨砂玻璃

打开后工具栏、卡片、工具框与代码块都不再自带不透明底板,透出壁纸与宿主皮肤;路径 / 行数这类标签静止时透明,悬停或聚焦才显出轮廓。开关下面九个旋钮分别调各面的不透明度:

旋钮管什么
工具栏顶部那条泳道的底板,以及浮动在正文上的「回到最新」胶囊
用户气泡你自己那条消息的底色
卡片与面板推理卡、工具框、系统提示词、备忘框等面板
代码块围栏代码块的底色
差异面板差异面板、文件标签,以及工具结果里的行内差异
滚动条槽位最右侧那条滚动条的轨道
产物标签一轮末尾那栏产物文件
用量与步骤胶囊「用量 … tok / … 个步骤」两枚计数胶囊
输入框宿主输入框的底板(阅读页与对话页都生效)

0% 是「这个面什么都不画」,100% 是关掉皮肤时那块不透明底板。分组按「是什么」而不是「在哪」(差异纸无论画在面板里还是工具「结果」页里,都归「差异面板」),而且只给本来就有底板的面配旋钮——工具状态与行数计数在基础样式里本没有静止底板,所以不接任何旋钮。

同一个皮肤可以再伸到对话页(独立开关):那里的代码块与用户气泡跟随上面这些旋钮;还有一个独立开关把对话页改成整页纯色底(主题底色 + 输入框上方一条淡出),与皮肤互不依赖。

壁纸

插件自带一张默认壁纸(assets/sample-gradient.png),第一次启动时由宿主放进读者的壁纸文件夹——新装上去打开就是这个样子,不用先自己找图。

  • 图片放在插件自己的文件夹里:点「打开文件夹」会建好并打开它,把图拖进去再点「刷新」就变成缩略图列表;点一张即生效,「清除」回到不设(这与「没有记录」是两件事:前者是你要无壁纸,后者才落到自带那张)。同名文件被替换后缩略图与背景都会更新。
  • 浏览器不知道这个文件夹在哪:它只按名字要图,宿主那半只在那个文件夹里、且只对图片扩展名作答(不含 svg)。
  • 压暗滑块把图混向主题底色,好让正文压在上面也看得清;开着磨砂玻璃时卡片糊的正是这张图。
  • 范围默认是整个窗口:侧栏与顶部栏也透出它(那两栏原本的底板被让开),输入框周围的底色跟着走;关掉「铺满整个窗口」就只覆盖阅读视图那一列,此时图片填满阅读页面(按「图片 ÷ 目标」的最大值取比例、居中裁掉溢出,小图会放大去填满)。整窗范围用 cover 填满。
  • 界面遮罩:整窗范围下,这两栏压在自己那份壁纸上的浓度——它们上面全是文字,0% 就是直接压在照片上。图只画一次、遮罩按窗口算一层,所以阅读区不会比旁边更暗。
  • 输入框上方那条淡出带是把宿主的不透明渐变改成「遮罩 + 同一份底图」,所以内容照样平滑淡出,只是淡入的从一块底色变成你的图;阅读、对话、轨迹三页用的是同一个抬升量。

正文显现

流式正文"长出来"的过程有三项可调:

  • 正文更新节奏(默认固定 60 次/秒):一次更新就是一次整个增长节点的重渲染 —— 尾部 markdown 重解析、词身份重算、挂上新的词元素,以及下面所有跟随器要量的布局。跟着屏幕刷新率走,意味着在这块 240Hz 屏上是四倍的工作量,而且节奏会跟着「上一帧花了多久」走。「跟随屏幕刷新」因此是显式选项,它的代价写在那一行自己的说明里;两种节奏驱动的是同一条显现轨迹(推进量是时间的函数),所以固定节奏只是把轨迹采样得稀一些。实测(同一台机器、同一页面、同样流式长文):3430 → 4435–4568 帧/20 秒(≈171 → 222–228fps)、掉帧 4 → 2、长任务 0,空闲时满帧 4800。
  • 逐词显现的模糊(默认关):参考配方让每个词淡入的同时把 1px 模糊化开,而 filter 不是合成器能独立动画的属性 ⇒ 每个正在显现的词每帧都要重绘自己那片区域;一个词的显现持续 350ms、而正文流里每秒约五十个词到达 ⇒ 任何时刻都有十几个这样的重绘重叠着跑。关掉后只剩淡入(观感差别是"清晰浮现"而不是"由糊变清")。
  • 逐词显现(默认开):关掉后正文直接出现,连词身份和时间线都不再产生(省掉的不只是动画,还有分词与那本 birth 账,markdown 那条路也不再挂上显现钩子)。推进节奏仍来自流缓冲,所以看起来还是一点点写出来。
  • 跟随到最新(默认逐帧滑行):滑行每帧写一次滚动位置,而每一次写都会产生一个滚动事件 ⇒ 滚动 spy、锚点补偿与各处测量都被它唤醒。切到直接贴底后,每次增长只写一次,这些路径一并安静下来;代价是内容"跳"到最新而不是滑过去。这个选择现在也管到卡片自身的长高:滑行时,「焦点思考展开」的卡片会缓入每一行新高度(是滑上去,不是跳一格),而且底边留在原处 —— 补偿逐帧追着那次缓动走;选直接贴底时,高度像以前一样瞬间到位(「动效」关掉或系统要求减少动效时同样如此)。
  • 自动收起更早流程(默认关):开着时,只要有一轮在流式,只有正在长的那一轮的过程保持展开,其余轮次全部折起 —— 包括本该保持展开的"未完成"轮次(中断 / 出错),也包括你之前点开过的(新的一轮开始时那些选择会被清掉)。折起的过程会卸载内容而不是隐藏,所以开着它时,正在长的那一轮之外的过程不参与渲染与布局。你自己点开的那一轮仍然保持展开,直到下一轮开始。
  • 思考卡自动跟随(默认跟随最新):思考卡内部一直是"每 840ms 前进 2 行、500ms 滑过去"(约 2.4 行/秒,大体是阅读速度,所以模型爆发时它故意落后)。三种模式:自动滚动保持这个按行速的节奏、跟随最新每步停在最新一行、手动滚动卡片自己绝不动。三者的接管、边缘渐隐与跟随交接完全一致。
  • 自动滚动速度(默认 2 行/秒):四档预设。节奏按整行量化,而默认那档在 840ms 节拍下算出的步长正好是 2 行 —— 也就是这张卡一直以来的步长,所以不改设置的人观感不变。
  • 焦点思考展开(默认开):开着时,正在被写入的那张思考卡会长高来显示内容,直到「展开阅读」那一档的上限(min(60vh, 560px))。判定发生在你正停在正文最下方、且某张卡正在被写入时;之后往上翻不会让它缩回去,只有你接管卡片、自己点「展开阅读」、或在跟随最新模式下这次思考结束,它才回到小卡(另外两种模式保持高度)。同时只有一张卡持有焦点,最新申请者获胜 ✓。焦点期间页面不再自动贴底 ✓ —— 但焦点只跟卡片自己的增长走:卡片自己的文本停下、旁白或工具卡开始流时焦点立即交还,页面恢复贴底 ✓。高度按整行增长(布局次数从"每次发布"降到"每行一次"),上限留在样式表里;「逐帧滑行」时每一行是缓入的,而「直接贴底」时是瞬间到位(见上一条)✓。展开态本来就不画那两条遮罩渐隐 ✓。关掉它时三种跟随模式依然有效,只是作用在小卡上 —— 和现在一样 ✓。

页面跟随与「回到最新」

  • 跟随只在有进行中的轮次时发生(判定与状态行、等待时钟读的是同一个 status === 'open')。没有轮次在跑时,内容再长也不会把你拉回底部 —— 那只是和你自己滚动较劲。
  • 轮次结束后还会多跟约 1.5 秒:一轮并不是在回答写完时结束,产物栏、用量/步骤、操作行都是在那之后才排布的;不留这一拍,它们就会落在视口下方,你还得再滑一下。
  • 三种"不动"是三件事:① 你接管(滚轮、触摸、PageUp/Home/向上键,或你自己往回滚)—— 跟随关掉,「回到最新」亮起 ✓;② 跟随被临时挂起(「焦点思考展开」期间页面本来就不该跟着卡片动)—— 页面只是暂时不动,别处长出来的高度不会被误读成"你滚开了",挂起一结束就自己接回去 ✓;③ 你在视图里输入(输入框 / 可编辑区)—— 跟随停下来等你,但不算你接管,也不会亮药丸 ✓。
  • 「回到最新」胶囊只在①之后出现;点它 = 回到最新并恢复跟随。②那种情况不该亮药丸 —— 以前会(而且亮起后再也回不来 ✗),那是被修掉的 bug 之一 ✓。

竖条滚轮

阅读列两边那两条宽度把手属于外壳,位置在滚动容器旁边而不是里面,所以在那上面滚轮原本什么都不会发生。打开这个开关(默认开)后,手势会转发给正文自己的滚动容器:

  • 一格一格的滑动由临界阻尼弹簧送出(单格与每次落地都是它),手感的两端可调:甩动与单格。
  • 连续滚动(间隔 0.06–0.20 秒,约 5–16 格/秒)改为按轮子自己的速率匀速带走——速度取「当前这一格 ÷ 最近三个间隔的平均」。这是为了跟浏览器的手感对齐:同样手速下普通滚动不是匀速的,所以更慢或更快的滚动都仍是一格一格。
  • 一次连续滚动要两个间隔才算成立(一个间隔不是节奏),停顿超过 0.2 秒就结束它;关掉开关后,事件原样留给浏览器,行为与没有这个功能时完全一致。

设置存在哪

  • 浏览器里一份(localStorage),宿主里一份(<instance home>/viewtune-settings.json)。宿主这份是真正跨重启的:GUI 跑在临时端口上,而 localStorage 按来源(scheme + host + port)分区,所以只靠浏览器那份,每次启动都是一个新的空来源——「每次退出 DSH,设置全没了」。
  • 页面改动后会防抖写入宿主,并在离开时补一次;只有宿主接受的那次写入才会被广播给全 App 的外观(例如壁纸与滚动条槽位)。

已知限制(以及「说不出来时它怎么显示」)

  • 被历史窗口截断的轮次不显示步骤数字。Harness 按消息条数分页,最上面那一轮可能只加载了一部分,它的步骤数是局部和、与过程记录里的绝对步数不可比——偏小的分母会误导,所以不显示;取而代之的是 「步骤记录」 标记,悬停提示「请完全加载该轮次记录后查看」。它只是说明:没有点击行为、没有 hover 高亮,也不会出现任何估算出来的数字。
  • 用量胶囊偶尔不出现属于有意为之:宿主只在能精确证明该轮计费数据时才给出用量。本插件跟随这一取向,不猜、不估算,也不为它加标记——缺数字就是缺数字。
  • 界面文案目前只有中文。宿主提供了语言座位,本插件也已经在借用它翻译宿主自己的两条文案(message.contextRecall / message.contextInjection),但插件自身的文案没有走本地化——做成完整的 zh/en 需要先给插件加一个 locale provider 边(要重启 Host)。这是权衡后的取舍,不是遗漏。

开发

构建

浏览器半边是预编译的 lib/client.js,Host 启动时直接加载它。仓库把编译结果一并提交,所以安装与分享都不需要构建:

npm ci                # 按仓库里的 package-lock.json 装依赖
npm run build         # src/ -> lib/client.js 与 lib/dsh-viewtune.js
npm run typecheck     # tsc -p tsconfig.json --noEmit,对着真实声明检查

用 npm ci 而不是 npm install:tsdown / lightningcss / typescript 都写在 ^ 区间上,只有锁文件能保证在别的机器上装出能复现当前 lib/ 的同一套工具链——npm run guard 里的 verify-build 正是这么比的。只有动了依赖才用 npm install 回写锁文件。

上游的 tsdown.config.ts 从一个不对外发布的 Harness 适配器取 externalClientBundle,所以在克隆出来的仓库里跑不起来。本仓库把它的真身(官方预设的 clientBundle(),Harness tag dsh-v0.1.5-rc.2)移植成了 scripts/client-bundle.mjs。产物契约不变,针对产物的断言依然有效。

改完记得同时提交 lib/:别人拿到的是这份产物,而不是让他在本地构建。

改代码

改动显示逻辑时,改 src/ 然后 npm run build。产物里的两处身份标记必须与 package.json 的 name 完全一致,否则整页会因为 loaded without registering "<id>" via __ModuleLoader__.load 而失败:

  • window.__ModuleLoader__.load({ id }) 的行 id(宿主由安装清单的包名派生);
  • 每个 CSS 模块的 tagId 前缀与 document.createElement("style") 的 data-plugin(HMR 按 plugin id 移除本插件的样式)。

tests/stock-install.test.ts 就是这两条的守卫;同一个测试还会检查本文档与 README.en.md 的安装命令与包名一致。

把克隆出来的仓库放在 node_modules 之外。 dsh plugin add 会在 profile 目录里跑 pnpm,而 pnpm 会清理 node_modules 下未在 package.json 中声明的目录——仓库连同 .git 可能被一起删掉。

验证

分两层,因为它们回答的是不同的问题:

npm test        # 源码层:Node 自带测试跑当前全部测试文件(31 个)
npm run guard   # 产物层:19 条不变式,全部针对构建出来的 lib/client.js

npm run guard 检查的是产物:模块表注册 id 与 require() 集合、注入的 CSS 字面量是否完整、轮次渲染顺序、收起控件的形状与淡出、工具栏几何、设置面板的三页与滑块的宽度、自带壁纸的三处拼写与文件本身,以及**src/ 与产物的对应关系与「重新构建仍能复现已提交的形状」**。最后一条是这类仓库唯一能做的「产物与源码一致」证明——字节相等不可用(压缩器输出本就不稳定),所以它比对的是契约面与样式表规则。

这套做法有个前提值得说明:能解析(node --check 通过)不等于正确。本仓库的历史大量是直接改压缩产物,出现过语法完全合法、却因为一个引用被删掉而在运行时抛错的情况——那类错误只有「名字是否有声明」这一层检查能抓住,或者「重新构建一次」能暴露。两条都在 npm run guard 里,而且每条新断言都做过反向自检(喂一份动过手脚的产物,确认它真的会失败)。

许可

本仓库按 MIT 发布,见 LICENSE。

它的起点是 aa2246740/dsh-better-display(MIT):阅读页签、流式动效与 Markdown 渲染来自那里。展示与 Markdown 部分源自 DeepSeek Harness(MIT)。动效参考 Transitions.dev。随包分发的默认壁纸是仓库里的 assets/sample-gradient.png,为本仓库自制,与代码同样按上面的 MIT 发布。