Introduction¶
Long sessions have a specific inconvenience in the DSH Web UI: the session view is lazily loaded, and early messages are not in memory by default. To return to a previous question, you can only repeatedly click “Load Older” or scroll to find the location. The longer the session, the more inefficient this action becomes.
The DeepSeek official website has a table of contents index on the right side; clicking it jumps to the corresponding content. dsh-session-toc brings this experience to DeepSeek Harness’ Web UI. The following sections introduce the plugin’s functionality, installation methods, and usage details.
What is this¶
dsh-session-toc (repository notload/dsh-session-toc) is maintained by notload, with the current version 0.2.0 and an MIT license. It adds a persistent, collapsible directory bar to the right center of each session page in the DSH Web UI: each user question in the session is a directory entry; clicking it scrolls and locates the corresponding message and highlights the current entry.
Two design points need to be clarified first:
- Directory entries come from the full session log. The host side reads the entire session log via
sessionQuery.readSessionto extract questions, without depending on nodes already loaded into the browser’s memory; early, unloaded messages also appear in the directory. - Zero-intrusion. The plugin does not modify any
@deepseek-ai/*built-in packages; it only mounts as a bundle plugin, following DSH’s normal path of “everything is a plugin”.
Core Features¶
The Directory Bar Itself¶
- Mounted on the
shell.overlayfloating layer, vertically centered on the right, click-through by default, but the items themselves are interactive. - Can be collapsed into a narrow button on the right side; click again to expand.
- Automatically hides when the current session’s user questions are below the threshold, preventing noise in short sessions.
Entry Source and Filtering¶
- Excludes injected contexts like
session-referenceandworkspace, keeping only real user questions. - When a user message carries descriptive text, the directory text uses the text directly; for pure images/files with no text, the filename is used as a fallback.
- The directory is always generated by reading the full session log on disk from the host; DSH’s context compression only changes the “memory” of the main session and does not touch the log, so directory entries remain complete and undamaged.
Clicking and Location¶
Every chat node in the DSH session view has a stable attribute data-chat-anchor-key on the DOM. When a directory item is clicked, the plugin uses it to precisely locate and scroll; image messages also have this attribute, so it does not rely on text or image matching.
If the target message is not loaded into the DOM, the plugin automatically loads it page by page using loadOlder before locating; if the node is never found and positioning is unreliable, it degrades to highlighting only the current entry.
Performance¶
- The host side implements a “process LRU cache + disk index” dual-layer throttling; switching sessions no longer repeatedly triggers a full
readSession. The disk index is located at$DSH_HOME/storages/session-toc/, persists across processes/reboots, and allows sessions to open instantly after switching. - When the directory exceeds 200 items, a fixed-row-height virtual list is enabled, rendering only the visible window ± buffer; entry data is fully retained, so clicking to locate is not affected.
- Listens to session snapshots; new questions are automatically added to the directory within about 1.2s, without needing to switch sessions or manually reload.
Appearance¶
- Three skin modes:
auto/light/dark, switchable. - Background opacity is adjustable, affecting only the background; text remains opaque.
- Selections are persisted to
localStorage(dsh-session-toc.theme/dsh-session-toc.bgAlpha), preserved across refreshes and sessions.
Fallback on Read Failure¶
When the host read fails (e.g., reporting SessionFormatUnsupportedError), the frontend no longer silently clears it: it degrades to a directory of “browser-loaded nodes” (partial availability) and displays a “Directory load failed (partially loaded content shown) + Retry” status bar.
Installation and Enablement¶
Prerequisites: pnpm is installed locally, and the DSH web profile exists (e.g., ~/.dsh/profiles/web).
Method 1: Clone from GitHub and install via link (recommended):
git clone https://github.com/notload/dsh-session-toc.git
cd dsh-session-toc
dsh plugin --profile web add link:$(pwd)
If $(pwd) does not work in your shell, write the full absolute path directly, for example on Windows:
dsh plugin --profile web add link:C:\Users\<your-username>\dsh-session-toc
Method 2: If published to npm, install the published version directly:
dsh plugin --profile web add dsh-session-toc
Verify the plugin is in the layer stack:
dsh plugin --profile web list
After the above steps, restart dsh web, visit the same URL in your browser, and you will see the directory bar on the right side of the session page.
Configuration¶
Directory parameters are passed to the host side via the config of apply in cordis.patch.yml. Note: The DSH client configuration pipeline is currently not fully connected, so the config received by the browser side is an empty object. The following parameters currently rely on the code’s default values and cannot be overridden by users (compare with lib/client.js):
| key | Default Value | Description |
|---|---|---|
minEntries |
1 |
Hide the directory bar when current session user questions are fewer than this value |
maxChars |
48 |
Maximum character count for a single directory entry text (adds ellipsis if exceeded) |
collapsed |
false |
Whether to collapse initially |
One discrepancy to note: the “Features” section of the README writes the auto-hide threshold as “Default 3 entries”, while the configuration table (compare with lib/client.js) writes minEntries default 1. The actual value follows the code.
Behavior and Security Details¶
The host side has implemented several layers of protection for directory data routing:
- The route does not carry CORS headers; cross-origin reading is blocked by the browser’s same-origin policy.
- Validates the browser origin signal carried by the request (
sec-fetch-siteor same-originOrigin); naked requests from curl, scripts, LAN hosts, etc., are all rejected with 403. - The
sessionIdmust belong to a session visible by the current host; otherwise, it is rejected. - Error responses do not reveal internal error details.
Development and Testing: npm test in the repository is equivalent to node --test --test-isolation=none --expose-gc.
Suitable Scenarios and Notes¶
Suitable for:
- Developers who frequently run long sessions in the DSH Web UI and need to review or locate early questions.
- Users with many images/files in messages: positioning relies on stable node keys rather than text matching, so image messages can also be accurately located.
Pre-installation notes:
- The plugin runs with the permissions of the current dsh process. It is recommended to check the source code before installation to confirm behavior. The license is MIT.
- Current client configuration cannot be overridden by users; the only adjustable items are interface items like the theme and background opacity within the directory bar; other parameters take effect based on code defaults.
- Requires
pnpmto be installed locally, and the web profile must exist.
Summary¶
dsh-session-toc solves the specific trouble of “can’t find that earlier question” in long sessions in the DSH Web UI: a persistent directory bar on the right, covering the entire session log, precise click-to-locate, a fallback path for read failures, and zero-intrusion to built-in packages. If you use DSH Web UI heavily in your daily work, you can give it a try.
- Plugin directory page: https://www.skillhub.cn/plugins/notload/dsh-session-toc
- GitHub repository: https://github.com/notload/dsh-session-toc
(The community plugin directory is an independent site and has no official affiliation with DeepSeek or Hyperplane.)