A Codex-style conversation navigator for the DeepSeek Harness Web GUI.
Install
# from npm (prebuilt)
dsh plugin --profile web add @hjj345345/dsh-sm-context-piano
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:hjj345/dsh-sm-context-piano
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
English documentation · 简体中文(默认)
GitHub: https://github.com/hjj345/dsh-sm-context-piano
npm: @hjj345345/dsh-sm-context-piano
A Codex-style conversation navigator for the DeepSeek Harness Web GUI.
Minimum supported version: DSH 0.1.7-rc.1.
The compatibility range also includes DSH 0.2.0-rc.2.
It adds a compact rail of horizontal keys beside the transcript and condenses a long conversation into semantic nodes that can be previewed and located. Users can scan the conversation structure, hover for summaries, and click or use the keyboard to jump to a target paragraph instead of repeatedly dragging the scrollbar to recover context.
This is navigation-only UI. It never mutates session content, trims model context, injects system prompts, or exposes an additional HTTP endpoint.
Why a piano-key navigator
Long-running agent sessions usually contain many user requests, model replies, tool calls, edits, and internal states. A normal scrollbar represents physical page position but says nothing about the meaning of each section.
The navigator reorganizes the transcript into recognizable nodes:
- Every user message becomes its own node;
- Continuous model output merges into one node;
- Tool calls, edits, reads, reasoning, and internal states never create keys;
- Model output separated by non-output content starts a new segment;
- The current reading node remains visible inside a fixed window.
The number of keys therefore does not simply equal the number of rendered rows. It more closely represents the meaningful conversation paragraphs a user can perceive.
Features
- Compact Codex-style keys — defaults to 2px thickness, 12px center pitch, and 20 visible keys, kept in a concentrated stack rather than compressed indefinitely for long history.
- Semantic nodes only — user messages and model-visible text are included; tool, edit, read, reasoning, command, partial, and other internal rows are excluded.
- Continuous-output merging — adjacent model text remains one key until non-output content breaks continuity; output from separate stages stays independent.
- Fixed-window browsing — when nodes exceed the limit, a fixed number is shown around the current reading position; selecting a top or bottom boundary reveals earlier or later history.
- Continuous hover wave — the whole rail is an interactive hit area, so gaps between keys still select the nearest node and smoothly adjust neighboring widths.
- Safe text previews — the hover card shows a title and excerpt, follows light/dark themes, stays inside the viewport, and always writes content as plain text.
- Fast paragraph jumps — click a key or press Enter/Space to scroll to the beginning of its message row.
- Replaces the official Turn Navigator — while plugin keys are available, the plugin hides DSH's right-side navigator; it restores the official navigator when disabled or when no navigable content exists.
- Reading-position tracking — scrolling immediately darkens and lengthens the current key and recenters the fixed window.
- Streaming incremental updates — existing key DOM is reused while model output or loaded history changes, avoiding flicker and preserving interaction state.
- Trilingual settings page — Simplified Chinese, English, and Traditional Chinese are supported, with Simplified Chinese as the default; the choice applies immediately and is persisted by DSH.
- Configurable layout — key thickness, center pitch, and maximum visible count can be changed, and the total rail height is recalculated automatically.
- Responsive settings UI — General, Display, About, and Install Command cards adapt to narrow screens; long commands wrap without colliding with the copy button.
- Keyboard and assistive-technology support — keyboard selection, activation, and dismissal are supported; the rail exposes a navigation role and accessible name.
- Theme and motion preferences — follows DSH light/dark styling and respects
prefers-reduced-motion. - Complete teardown — unloading removes DOM, styles, listeners, observers, timers, and animation frames without leaving page side effects.
Real-world application
The plugin adds a key navigator beside the conversation, with hover previews and reading-position synchronization for long conversations.
Quick start
Install from npm
dsh plugin --profile web add @hjj345345/dsh-sm-context-piano
Refresh or reopen the DSH Web GUI after installation, then select sm-context-piano from the Settings navigation.
Local development link
dsh plugin --profile web add link:C:/path/to/dsh-sm-context-piano
Controls
| Action | Result |
|---|---|
| Move the pointer over the rail | Select the nearest key, expand the wave, and show its paragraph preview |
| Click a key or the current rail position | Jump to the paragraph currently being previewed |
| Scroll the transcript | Update the current key and the fixed visible window |
ArrowUp / ArrowDown |
Move between keys visible in the current window |
Home / End |
Select the first or last key in the current window |
Enter / Space |
Jump to the selected key node |
Escape |
Close the preview and clear the hover state |
After a top or bottom boundary key is selected, the window is recalculated immediately so earlier or later nodes enter the visible range.
Settings page
The plugin registers a first-level DSH Settings section directly after the official Agent Presets entry. Third-party section navigation intentionally uses DSH's official fallback gear icon.
General settings
| Setting | Default | Description |
|---|---|---|
语言/Language |
Simplified Chinese | Supports Simplified Chinese, English, and Traditional Chinese; changes only this plugin's settings-page copy |
The language choice is stored independently by the plugin. It does not change the global DSH locale; the first-level section name and the navigator's accessibility label continue to follow the DSH system language.
Display settings
| Setting | Default | Range / behavior |
|---|---|---|
| Enabled | On | Disable or re-enable the navigator at any time |
| Key thickness | 2px |
1–4px |
| Key spacing | 12px |
6–18px, measured between adjacent key centers |
| Maximum visible keys | 20 |
5–40; a fixed window is used above this limit |
| Restore defaults | — | Restores language, enablement, and every display parameter |
Total rail height is derived automatically:
(maximum visible keys - 1) × key spacing + key thickness
The defaults produce (20 - 1) × 12 + 2 = 230px.
About and install command
The About card shows version, release date, author, email, the GitHub repository link, and the official npm package name and link. The Install Command card displays the complete command in its own code surface and provides a one-click copy button.
Settings screenshots
The following screenshots show the Chinese settings page, the plugin enablement and display controls, and the English locale.
How it works
- Read ordered nodes loaded in the active conversation through DSH's session-scoped UI API;
- Convert user messages and model-visible text into safe navigation descriptors while filtering every non-output node;
- Merge assistant output by continuity and assign stable segment keys to separated output;
- Match semantic nodes to rendered rows through
[data-chat-anchor-key]; - Calculate the current node from the reading line and render only a fixed window centered around it;
- Keep layout synchronized through the scroll container, MutationObserver, ResizeObserver, and animation-frame scheduling.
Keys are incrementally reused through stable identities, so streaming replies do not repeatedly clear and rebuild the whole rail.
Compatibility and boundaries
- Designed for the DeepSeek Harness Web profile and the current ChatView anchors:
[data-chat-flow],[data-chat-anchor-key], and[data-conversation-scroll]. - Only history already loaded into ChatView receives keys; older records do not appear before DSH loads them.
- Tools, edits, commands, reasoning, and internal states never create keys or enter hover previews.
- Visible output runs separated inside one DOM row may create multiple keys, but Harness row-level anchors mean they all jump to the beginning of that message row.
- The rail safely hides when the page is too narrow, its gutter would overlap the transcript, or no navigable nodes exist.
- The official right-side Turn Navigator is hidden while plugin keys are visible, and restored when the plugin is disabled, unloaded, or has no navigable nodes.
- The current build environment requires Node.js
^22.19.0 || >=24.0.0.
Security and privacy
- Does not mutate Session, model context, system prompts, or conversation data;
- Registers no extra HTTP route and sends no plugin-owned network request;
- Persists preferences through the official DSH settings namespace rather than separate private browser storage;
- Writes preview content with
textContentand never executes conversation HTML; - Keeps user transcript content out of error messages;
- Removes rail DOM and conversation-bound listeners when disabled, and releases global observers and settings subscriptions on full unload.
Development and verification
Requires Node.js ^22.19.0 || >=24.0.0 and pnpm.
pnpm install
pnpm verify
pnpm verify runs:
- TypeScript project-reference and type checks;
- Production host and client bundles;
- DSH client-module wrapping;
- Output-segmentation, fixed-window, and settings-boundary logic checks;
- Built-artifact smoke checks;
- jsdom page and interaction integration checks.
Current automated coverage includes 21 logic assertions, 4 built-artifact smoke checks, and 14 jsdom integration scenarios.
Internal design and acceptance materials remain in the repository's docs/ directory and are not included in the npm package.
FAQ
Why are there no keys for tool calls or edit records?
Keys are navigation targets for content users directly perceive. Tools, edits, reads, reasoning, and internal states only act as continuity boundaries for model output.
Why does a long conversation not show every key at once?
The navigator uses a fixed-size window so spacing is never compressed merely to fit all history. Select a top or bottom boundary node to progressively reveal earlier or later content.
Why does the left Settings name not change with the plugin language?
The plugin language controls only the settings page. The DSH section name and the rail's accessibility label intentionally continue to follow the DSH system locale.
Why are some older messages missing from the rail?
Keys cover only history already loaded into ChatView. DSH must load those older records before the plugin can create their navigation nodes.
Do settings survive a refresh?
Yes. Language, enablement, and display parameters are persisted through the DSH settings namespace.
License
This project is open source under the MIT License.
Changelog
v1.2.8 · 2026-09-30
- Fixed DSH 0.2.0-rc.2 client plugin loading by adding the
dsh-client-modulesinjection and updating the related development dependencies; - Updated the DSH 0.2.0-rc.2 compatibility notes, smoke checks, and npm build artifacts so the published package contains loadable host and client bundles.
v1.2.7 · 2026-09-29
- Adapted to DSH 0.2.0-rc.1 and expanded the settings API and dependency compatibility ranges;
- Changed display settings to draft editing with a single save action, added saving feedback and a restore-default confirmation dialog to avoid write churn and UI stalls;
- Increased the maximum visible key count from 30 to 40 and fixed settings-page overlay layering and dialog interaction issues.
v1.2.6 · 2026-09-26
- Adapted to the DSH 0.1.7-rc.1 session and Chat APIs, using the session-scoped UI slot to identify the current conversation;
- Fixed settings Remote injection and
{ok, value}response handling so settings can load, update, and persist; - Added the npm package
engines.dshdeclaration and documented replacement of the official Turn Navigator.
v1.2.5 · 2026-09-25
- Adapted to the DSH 0.1.7-rc.1 settings API by moving plugin settings into profile configuration, retaining the
sm-context-pianoentry ID to migrate existing settings; - Switched the client to
remote.settingsfor reading, updating, and resetting configuration, with external change notifications and revision checks to prevent stale writes; - Raised the minimum supported version to DSH 0.1.7-rc.1 and updated the related dependencies, configuration schema, and compatibility tests.
v1.2.4 · 2026-09-09
- Improved piano-navigation rail positioning on ultra-wide screens: snap toward the viewport edge when there is enough space, while staying close to the content when the margin is tight;
- Added a smooth horizontal transition and ensured hover previews remain correctly positioned after the rail moves;
- Added grouping and integration coverage for rail-edge positioning, horizontal transitions, and responsive layouts.
v1.2.3 · 2026-09-08
- Fixed the piano-navigation rail from obscuring settings dialogs by detecting visible DSH
role="dialog"elements, suspending the plugin navigation while a dialog is open, and restoring it after closing; - Added integration coverage for visible dialogs, hidden dialogs, and rail restoration while preserving the official Turn Navigator's hidden state;
v1.2.2 · 2026-09-07
- Added DSH 0.1.2-rc.1 Chat target support at that time; see the top of this document for the current minimum;
- Read conversation nodes from the DSH 0.1.2-rc.1
uiConversationChat target instead of the legacy Session snapshot; - Hide DSH 0.1.2-rc.1's built-in Turn Navigator only after this plugin mounts successfully, and restore it when the plugin is disabled or unavailable;
- Added integration coverage for the DSH 0.1.2-rc.1 ChatView, TurnNavigator, and historical turn projection.
v1.2.1 · 2026-09-07
- Fixed piano-navigation rail display and binding in DSH 0.1.2-rc.1 environments;
- Switched hover targeting to actual bar geometry so empty rail space no longer triggers an incorrect preview;
- Added fallback binding to the conversation scrollport when the legacy flow marker is absent, with automatic rail recovery after external DOM removal;
- Adjusted the navigation overlay stacking and hid it while a DSH dialog is open to prevent UI obstruction;
- Added integration coverage for binding, positioning, recovery, and dialog scenarios.
v1.2.0 · 2026-09-02
- Fixed DSH settings-namespace compatibility with newer dependency versions so the plugin always registers its namespace as a string;
- Expanded host compatibility declarations for
@deepseek-ai/cordis,@deepseek-ai/dsh-settings, and@deepseek-ai/schemastery; - Added matching smoke and integration checks for host registration, peer compatibility, and the settings-page version/date metadata.
v1.1.2 · 2026-08-29
- Version updated to v1.1.2.
v1.1.1 · 2026-08-29
- Unified the plugin's user-visible version marker as
v1.1.1; - Improved the install-command card's light/dark theme backgrounds and dark-theme text contrast.
v1.1.0 · 2026-08-28
- Fixed the plugin dependency contract so host core packages can no longer be hoisted over the host-provided versions;
- Moved
@deepseek-ai/dsh-settingsand@deepseek-ai/schemasteryto host-provided peer dependencies; - At that time, the development build baseline moved to DSH 0.1.1-rc.2; see the top of this document for the current minimum.
v1.0.0 · 2026-08-21
Initial release:
- Added a Codex-style piano-key navigator covering user messages and model-visible text output only;
- Added continuous model-output merging while filtering tools, edits, reads, reasoning, commands, and internal states;
- Added fixed-window browsing, active-node centering, boundary-node paging, hover previews, and fast jumps;
- Added scroll-position tracking, streaming incremental updates, and stable DOM-node reuse;
- Added a first-level settings page with General, Display, About, and Install Command cards;
- Added immediate, persistent switching between Simplified Chinese, English, and Traditional Chinese, defaulting to Simplified Chinese;
- Kept the DSH section name and rail accessibility label tied to the DSH system locale;
- Added enablement, key thickness, spacing, maximum visible count, automatic rail height, and restore-default controls;
- Added one-click install-command copying, responsive settings layouts, narrow-screen wrapping, and light/dark theme support;
- Added mouse and keyboard controls, reduced-motion support, and complete teardown;
- Validated host/client integration, the settings schema, built artifacts, and jsdom interactions.
Contributors
Thank you to everyone who contributes discussions, suggestions, testing, and code to this project. Special thanks to:
- @amazing-fish — submitted PR #3, proposing and implementing adaptive rail edge positioning.
Links
More in this category
zhu1090093659/dsh-web#packages/dsh-task-board★ 8707
Task board for the dsh web GUI: a sidebar multi-column kanban whose cards run in real DSH agent sessions and can also be scheduled with cron expressions, executed host-side even with the browser closed.
zhu1090093659/dsh-web#packages/dsh-web-all★ 8707
Plugin and skin collection for the DSH Web UI: task board, Git graph, right-side panel, remote mobile UI, pet, live token stats, and a skin center.
MeteorNOX/DeepSeek-Balance-Whale-Widget★ 4719
A fixed-corner whale widget for the DSH web GUI — balance, today's usage and per-turn cost with peak/off-peak pricing, editable balance-alert and daily-budget bubbles, a module-based custom bubble queue with A/B weighted choices and random lines or images, 30+ vendor templates (OpenAI, OpenRouter, Kimi, SiliconFlow, Ark, Zhipu, MiniMax and more) with per-model balance and subscription quota, plus task-end sound, imported audio, custom roles and a resource manager. Local-only, no telemetry.
ccch1mneyyy/dsh-TUI★ 4557
Claude Code-style full-screen terminal UI: pixel-whale header, live status line, and streaming thought expansion.
omdsh-dev/DSH-better-sidebar★ 4153
Full sidebar workbench with file rendering and editing, terminal, Git, and subagents; third-party plugins can register new tabs.
Devin-AXIS/deepseek-design#deepseek-idesign★ 1454
Visual design studio for websites, app prototypes, posters, cards, reports, and magazines, with templates, direct element editing, selection-aware AI draft handoff, and export.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.