dshbase

插件目录 / Developer / dsh-conversation-rail

dsh-conversation-rail

已验证 · 实测可装 dingyi580

✓ 持续维护 基于 2 个官方 DSH 包

查看 GitHub ↗ ← 返回插件目录

0Stars
0Forks
0未关闭 issue
—语言
2026-08-19最近推送
跨平台平台

功能简介

Session minimap for DSH Web — one bar per turn, hover to preview, click to jump · DSH 会话小地图:一根杠一轮对话,悬停预览,点击跳转

✅
我们的评价
可用 — 实测通过,早期项目

Session minimap for DSH Web — one bar per turn, hover to preview, click to jump · DSH 会话小地图:一根杠一轮对话,悬停预览,点击跳转 实测能干净安装、正常启动。早期项目,但功能可用。

「已验证」表示我们的自动化 CI 在干净 profile 里实际执行了 dsh plugin add 并启动成功——仅此而已。功能描述与版本兼容性均为作者声明。这不是安全审计,也不代表对第三方代码的背书。

README

dsh-conversation-rail · session minimap

English | 中文

A locator for long conversations in DSH Web. A vertical rail sits along the left
edge of the conversation, one bar per turn; hover a bar for a preview card,
click it to jump to that turn.

  ▏─────                 ┌──────────────────────────────┐
  ▏───────────           │ Can you patch this without…  │  ← question (one line, dark)
  ▏━━━━━━━━━━━━━━  ◀━━━━━┤ CRLF is already ruled out…   │
  ▏──────                │ only the legal re-encodes…   │  ← answer (up to four lines, dimmed)
  ▏────────              └──────────────────────────────┘
  • Bar length = how much text that turn holds (square-root compressed, 10–34px).
  • The bold bar = the turn currently at the top of the scroll area.
  • The preview card carries prose only: your question plus the assistant's plain
    text. Fenced code blocks, tool calls, shell commands, reasoning traces and
    injected context never reach the card — you cannot skim JSON.

It draws the whole session, not the loaded window

Conversation history is paginated: the front-end snapshot usually holds only the
most recent stretch, so an 8-turn session may have 1 turn in the window. The
rail is not bound by that:

  • The skeleton comes from the host's outline endpoint
    (GET /dsh-conversation-rail/api/outline?sessionId=). The host reads the full
    log with ctx.sessionQuery.readSession(), folds it into a table of contents of
    roughly a hundred bytes per turn, and returns that — the history itself never
    crosses the network.
  • The live snapshot overrides the part that is loaded: it carries jumpable DOM
    anchors, and for a turn that is still streaming it is the only current source.
    The two are aligned by the user/message event seq, live winning over outline.
  • Clicking a bar that isn't loaded yet calls session.loadOlder() repeatedly
    until that turn enters the window, then jumps. The bar pulses while paging, with
    a ceiling of 40 pages — better to not reach a turn than to page through an entire
    log because of one click.

The outline uses readSession rather than the lighter filterEvents because the
latter does not return source. The user/message event type carries both real
questions
and context injected by agent.inject() (file-change notices,
AGENTS.md, skill bodies…); the official docs state all three project content
verbatim and are told apart by source. Without that field, injected context
would be drawn as turns.

How it attaches

It takes one seat: conversation.session.header.utilities. Not to draw anything in
the header — that slot is session-scoped, so the component receives the framework's
useSession snapshot hook and sessionId, and its lifetime follows the session.
The component renders null in the header; the actual rail is a fixed overlay on
body, aligned to the measured rectangle of [data-conversation-scroll]. It stays
out of the host layout, so switching skins, collapsing the sidebar or changing the
grid cannot squeeze it.

Turn data comes from ConversationSnapshot.chat: walk order, open a turn on a
user node, attribute the following assistant-step text blocks to it. Jumping
uses the host's own anchors ([data-chat-anchor-key]), the same path its internal
scroll positioning takes.

Known boundaries

  • The outline is fetched once per session. New turns arrive through the live
    snapshot and do not trigger a refetch; only leaving and returning to the session
    refetches (a 5-second host-side cache absorbs the back-and-forth).
  • Jumping to a very early turn loads every page between it and the window.
    That is what pagination means: to show turn 1, everything from there up to the
    loaded window has to come in. Jumping to recent turns pages almost not at all.
  • If the outline endpoint fails, the rail degrades to drawing only the loaded
    stretch rather than disappearing.
  • Previews are rendered as plain text, not markdown: leading #, -, 1. and
    emphasis marks are stripped, fenced code is removed entirely.

Install

dsh plugin --profile web add github:dingyi580/dsh-conversation-rail

Then restart dsh web (a newly assembled plugin needs a restart; later code changes
can be hot-reloaded with dev_reload_package).

Installing from a local checkout

Put the plugin at ~/.dsh/plugins/dsh-conversation-rail, then add two entries to
~/.dsh/profiles/web/package.json:

{
  "dsh": { "profile": { "bundles": ["…", "dsh-conversation-rail"] } },
  "dependencies": {
    "dsh-conversation-rail": "link:/Users/<you>/.dsh/plugins/dsh-conversation-rail"
  }
}

and link it into the profile's node_modules:

ln -sfn ../../../plugins/dsh-conversation-rail ~/.dsh/profiles/web/node_modules/dsh-conversation-rail

Build

npm run build       # tsc for the host entry + tsdown for src/client → lib/client.js
npm run typecheck   # type check only

lib/ is committed so the plugin installs from GitHub without a build step.
Assembly goes through cordis.patch.yml plus the profile's dsh.profile.bundles.

License

BSD-3-Clause

安装

🧩 让 Agent 自动装(推荐)

装一次目录插件,之后本站所有插件都能让 DeepSeek Harness 自动找、自动装:

dsh plugin add dshbase-catalog

然后对 agent 说「帮我装 dsh-conversation-rail」,它会在目录里找到并自动安装。文档:dshbase-catalog · 已验证场景包。

该插件是 GitHub 源码(未发 npm)——直接从仓库装:

Web profile:

dsh plugin --profile web add github:dingyi580/dsh-conversation-rail

Headless(CLI)profile:

dsh plugin --profile headless add github:dingyi580/dsh-conversation-rail

实测报告

验证通过:从 GitHub 源码完成 L1 安装 + L2 加载 + L3 运行(dsh 0.1.0-rc.6)。

安全:尚未扫描——我们的每日静态扫描将很快覆盖它。

分享徽章

Developer 里更多

浏览全部 7819 个插件 →