DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Ui Turn Rail — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins

@huanghanheng/dsh-ui-turn-rail

Ui Turn Rail

DeepSeek Harness Web GUI 的回合进度栏插件:在对话滚动区域上方显示固定的点状条,提供每回合问题摘要、一键加载深层历史记录和 AI 选项摘要

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add @huanghanheng/dsh-ui-turn-rail@0.1.3
README兼容性版本

兼容性与来源证明

Ui Turn Rail 以 @huanghanheng/dsh-ui-turn-rail 发布,当前版本为 0.1.3。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
npm
Registry 更新时间
2026/8/26

版本

0.1.3stable
2026/8/26
0.1.0stable
2026/8/25

相关插件

正在加载相关插件…

最新版
0.1.3
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
35.7 kB
文件数
14
Surface
web
许可证
MIT
发布源
npm
GitHub
★ 0
周下载
0
最近提交
2026/8/26
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 ui-customization 分类下经过校验的插件。

Web App@deepseek-ai/dsh-web-appdsh 浏览器界面捆绑包:位于 dsh-base 之上的 Web 补丁层,加上运行时粘合插件(提供前端 dist、Web 界面提示符、bash 运行时变量和 URL 行)Experimental Agent Team Web Profile@deepseek-ai/dsh-experimental-agent-team-web-profile用于 Agent Teams Remote 和 UI 插件的实验性 Web 配置层Remote Web Ui@linxin666/dsh-remote-web-ui通过扫码配对访问 dsh Web GUI,共享一个官方界面:设置按钮旁的二维码可将手机和 PC 配对到同一个 Web GUI(手机采用竖屏触控适配层,PC 使用完整桌面界面),通过一次性令牌和 rClient Ui Git Graph@linxin666/dsh-client-ui-git-graph外部 dsh Web GUI 插件:空会话 Git 分支选择器和 Git 图,包含实际的主机端 Git 操作与防护,作为 dsh 配置文件包

README

dsh-ui-turn-rail

🌐 Language / 语言: English · 简体中文

Turn progress rail plugin for the DeepSeek Harness Web GUI: a sticky dot strip pinned to the conversation scrollport, one dot per loaded turn, with per-turn question summaries, one-click deep history loading, and summaries for AI-option picks.

GitHub topics: dsh-plugin · deepseek-harness


Features

  • Always-visible rail. The dot strip is sticky to the conversation scrollport, so it stays in view while the transcript scrolls — even in very long conversations.
  • One dot per turn whose question is loaded, plus dashed placeholders for turns whose question is still outside the window. AI replies and reasoning never count as a loaded question: a turn whose question has not been paged in yet stays a placeholder.
  • Question summaries. Hover a dot to see that turn's first question as a one-line preview. Both typed input (user nodes) and picked AI options (steering nodes) produce summaries.
  • One-click deep-history load. Click a placeholder and the plugin pages every older batch until the target turn's question is actually in the window (a page boundary can land a turn's first node while its question sits in an older page), then jumps straight to that question row.
  • Click a loaded dot to scroll the transcript to that turn's question.
  • Scrollable dot window. The rail shows about ten dots at a time with internal scrolling; the active turn's dot auto-follows into view as the reader moves.

Security

  • Presentation only. The rail renders facts already present in the session snapshot. It never produces a model-visible input, never writes the session log, makes no network requests, and touches no credentials.
  • Model Experience: nothing reaches a model request; token effect none; KV-cache effect none.
  • No new privileges. The host instrumentation (below) adds one read-only slot to the chat view; it introduces no new RPCs, permissions, or secrets handling.
  • Data lives in the host. All derivation (turn order, node→turn mapping, summaries) runs against the client-side ChatSnapshot; the rail holds no session state of its own.

Requirements

A DeepSeek Harness checkout (or the published @deepseek-ai/dsh-* packages) with the host instrumentation applied — the rail registers into the conversation.chat.rail seat that ui-conversation's chat view must declare (see below). Without the seat, the plugin loads but renders nothing (the seat renders fallback: null).

Installation

The plugin supports two installation routes. Neither automates the host instrumentation — that is a source-level patch to the harness checkout (see Host instrumentation) and must be applied and rebuilt regardless of how the package is installed.

Route 1 — bundle install via dsh plugin (recommended)

This repository is a DSH bundle: its package.json declares dsh.bundle.patch → ./cordis.patch.yml, so the profile plugin manager installs it as a patch layer and the patch inserts the plugin into the web profile's browser roster.

# From the git repository (no npm publish needed):
dsh plugin --profile web add @huanghanheng/dsh-ui-turn-rail

# Or, once published to npm (shorter spec):
dsh plugin --profile web add @huanghanheng/dsh-ui-turn-rail

dsh plugin runs pnpm add in the profile directory and reconciles dsh.profile.bundles automatically: a dependency whose manifest declares dsh.bundle.patch joins the layer stack.

Then apply the host instrumentation to the checkout the profile runs from — the seat must exist for the rail to render. A ready-made patch ships in this repository, applied in one command (then rebuild the web client):

scripts/apply-instrumentation.sh /path/to/harness-checkout
(cd /path/to/harness-checkout && pnpm run build)

Route 2 — manual npm install

The package publishes to npm with build artifacts committed (lib/), so it installs like any package:

# In the profile directory the app runs from (or the app itself):
npm install @huanghanheng/dsh-ui-turn-rail
# or: pnpm add @huanghanheng/dsh-ui-turn-rail

A manual npm install does not add the bundle layer automatically — declare it in the profile manifest so the patch inserts the plugin row:

// $DSH_HOME/profiles/web/package.json
{
  "dependencies": { "@huanghanheng/dsh-ui-turn-rail": "^0.1.0" },
  "dsh": { "profile": { "bundles": ["@huanghanheng/dsh-ui-turn-rail"] } }
}

Or simply run dsh plugin --profile web add @huanghanheng/dsh-ui-turn-rail, which performs the install and the bundle-layer reconciliation for you (equivalent to Route 1).

Then apply the host instrumentation and rebuild, exactly as in Route 1.

Host instrumentation (cannot be packaged)

The seat declaration lives in ui-conversation's slot contract, and the jump/paging gestures must operate ChatView's private scroll anchoring — neither can be delivered as a plugin, so dsh plugin add cannot automate it. The repository ships the exact change as patches/chat-rail-seat.patch (against harness master b150a551b8); apply it with scripts/apply-instrumentation.sh or git apply --3way, then rebuild. If your checkout has drifted, hand-apply the edits below. These are the exact changes:

packages/client/ui-conversation/src/client/contract/slots.ts

  1. SlotMap entry:
    'conversation.chat.rail': { kind: 'single'; scope: 'session'; owner: ChatTurnRailOwnerProps }
    
  2. Owner currency type:
    export interface ChatTurnRailOwnerProps {
      currentTurn: number | undefined
      loadingOlder: boolean
      hasMore: boolean
      onJump: (key: string) => void
      onLoadOlder: () => Promise<void>
    }
    
  3. Add 'conversation.chat.rail' to the PropsRenderSlots union in ChatViewSlotProps.
  4. Widen the injected paging contract to return the promise:
    loadOlder: () => Promise<void>
    

packages/client/ui-conversation/src/client/apply.ts

Declare the seat in the chat view entry's children:

children: {
  'conversation.chat.node': { kind: 'keyed', scope: 'session', inject: CHAT_NODE_INJECT },
  'conversation.message.images': { kind: 'single', scope: 'session' },
  'conversation.chat.rail': { kind: 'single', scope: 'session' },
},

packages/client/ui-conversation/src/client/chat/ChatView.tsx

  1. Node key → turn map for scroll-position attribution:
    const chat = useSession(s => s.chat)
    const turnByKey = useMemo(() => {
      const map = new Map<string, number>()
      for (const turn of chat.timeline.turnOrder) {
        for (const key of chat.locations.getTurn(turn)) map.set(key, turn)
      }
      return map
    }, [chat])
    
  2. Track currentTurn in the scroll handlers (set it from turnOf(anchorKey) or the latest turn when pinned to the bottom).
  3. loadOlderAnchored returns the paging promise:
    const loadOlderAnchored = (): Promise<void> => {
      // ...existing paging-anchor logic...
      return loadOlder()
    }
    
  4. Render the seat with the owner currency:
    {renderSlot('conversation.chat.rail', {
      currentTurn,
      loadingOlder,
      hasMore,
      onJump: jumpTo,
      onLoadOlder: loadOlderAnchored,
    }, { fallback: null })}
    

Development

pnpm install
pnpm vitest run tests/        # unit tests (model + component, jsdom)
pnpm bundle                   # tsdown client bundle (needs the harness's clientBundle preset)

The tests cover the turn model (tick derivation, typed/AI-option summaries, placeholders) and the component (jump, one-click paging past page boundaries, active-dot follow, window scroll).

License

MIT