# dsh-client-ui-timeline — DSH conversation query navigator (ZCode TurnNavigator style) A DSH plugin that brings ZCode desktop's **turn navigator** to the DSH Web GUI: a column of small dashes at the **left edge** of the conversation — one dash per user query (steering follow-ups included), visible whenever the window is wide enough: - **Scroll-follow**: the dash of the query you are on stretches and highlights (2.6×), neighbours fade by distance, the running last query stays lit; the rail auto-scrolls to follow. - **Hover** a dash: a preview bubble appears to its right (bold 2-line user question + 3-line assistant reply, ≤2 paragraphs, 220-char cap; shows "暂无助手正文" when empty, "助手仍在工作" while running). - **Click** a dash: that query's message row smoothly scrolls to the top of the viewport (instant with `prefers-reduced-motion`); unrendered older history is auto-loaded via `loadOlder` (up to 80 pages) before jumping. - Hidden when fewer than 2 queries, or when the conversation is narrower than 640px (ZCode's original threshold was 864px). [中文说明](./README.md) --- ## Install In your DSH profile (e.g. `desktop`), edit `profiles//package.json`: 1. Add to `dependencies` (`` = the full 40-char hash of the commit you want to pin): ```json "dsh-client-ui-timeline": "github:hhb1028/dsh-client-ui-timeline#" ``` 2. Add `"dsh-client-ui-timeline"` to the `dsh.profile.bundles` array. 3. Run `pnpm install` inside `profiles/`. 4. Restart DSH. The package ships its own `cordis.patch.yml` (insert id `ui-timeline-scrubber`) applied via `dsh.bundle.patch`; do **not** re-insert the same id in your profile's `cordis.patch.yml` (the Loader throws on duplicate loader entry id — same trap as vision-toolkit / meow-smooth). ## Compatibility - Developed against **DSH Desktop 2.0.2** (`@deepseek-ai/*` `0.1.1-rc.2`). - Depends on the chat node shape and the `[data-conversation-scroll]` / `[data-chat-flow-key]` DOM contract. - A DSH major upgrade may change those shapes/contracts and break the feature; when that happens the feature hides silently without affecting DSH itself. ## Uninstall Remove the dependency and the bundles entry from `profiles//package.json`, run `pnpm install`, restart DSH. ## Implementation notes (vs the ZCode original) - Original: the `TurnNavigator` component in `out/renderer` (i18n under `chat.turnNavigator.*`), mounted beside the virtualized conversation list; `onJumpToQuery` scrolls the `data-row-id` row to the viewport top and polls `scrollToIndex` for 12 rAF frames while the row mounts. - This plugin: DSH conversations are not virtualized — every row is in the DOM, so coordinates come straight from `getBoundingClientRect` on `[data-chat-flow-key]` rows; data path `sessions.list.current` → `scope(id)` (ctx proxy) → `sessionOf(ctx)` → `getSnapshot().chat.{order,nodes,timeline}`; one dash per `kind:user` / `kind:steering` node, preview from the first `assistant-step` with a body in that turn. - Visual spec mirrors the original: 10px per dash, 12×2px rounded dashes, scaleX distance fade (2.6/1.7/1.25), 320px bubble offset 8px right, line-clamp 2/3, 220-char cap, hidden scrollbar; colors use DSH's `--dsw-alias-*` variables to follow the theme. - Pure browser half (`window.__ModuleLoader__` module, id must equal the package name), zero build, never touches dsh itself; the host half is an inert empty plugin. All host access is guarded: upstream shape changes degrade to "feature hidden", never blocking the web boot. ## License MIT