
Security News
Deno Goes the Way of the Dinosaur
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.
dsh-turn-navigator
Advanced tools
Smoothly Turn Nav (Smoothly TN): full-history piano-key turn rail for DeepSeek Harness (dsh) web conversations — see every turn at a glance, hover to preview, click to jump anywhere, and replace the official (non-disableable) turn rail.
Smoothly · 思磨力 — brand · 中文名:思磨力轮次胶囊条
English · 简体中文
Every turn of your conversation, one glance away.
Smoothly Turn Nav (Smoothly TN) — 思磨力轮次胶囊条 — is an external plugin for DeepSeek Harness (dsh) that puts a piano-key turn rail on the right edge of every conversation — a vertical column of tiny capsules, one per turn. It gives you a full minimap of the conversation: every turn ever made (not just the ones currently loaded), hover previews, click-to-jump to any turn's start, and follow-scroll highlighting. It can also replace the official built-in turn rail, which has no off-switch of its own.

In the default DSH web UI, the official turn rail historically showed only the currently loaded window of turns — in a long conversation, most turns are invisible until you scroll and load more. As of dsh 0.1.3-alpha.1 the built-in rail also gained full-session scope and out-of-window jumps through a host-side turnOutline projection, but it still cannot be switched off. Smoothly TN solves the long-session problem and stays fully replaceable:
turnOutline projection → the localized turn number (Turn N, always the first line). The response preview comes from the same host projections (the window's own response first, turnOutline.response as the whole-log fallback, 120 chars). A machine-woken turn (goal continuation, plugin waking, background-job notice, subagent settlement, compaction checkpoint — turns that have no human prompt by construction) therefore shows its turn number plus the response preview, never a placeholder or injected text.| 🗺️ Full-history minimap | All turns visible immediately — read from the persisted session log as data, zero prepends into the conversation flow on open (long sessions stay responsive) |
| 🎹 Piano-key design | One capsule per turn, ~3px tall, right-aligned on the right edge; auto-sizing (up to 30vh) with an internal hidden scrollbar |
| 🌊 Wave hover | Hovered capsule glows with the theme color and widens 150% leftward; its two neighbours widen 125% — a ripple across the rail |
| 💬 Rich tooltip | Turn number, timestamp, prompt, and response preview (prompt fallback chain: the journal's full first human message → the window's bounded host preview → the host turnOutline projection → the localized Turn N; the response preview comes from the window/turnOutline projections), clamped inside the viewport |
| 🎯 Jump to any turn | Precise scrollTop targeting (no scrollIntoView fights); out-of-window jumps extend the window on demand with a "Locating turn N…" pulse + bubble; the oldest-turn jump loads to the true first turn (hasMore = false) |
| 👁️ Follow-scroll highlight | The capsule of the turn at the reading line is tinted as you scroll — and the rail's own viewport keeps the active turn in view |
| ⬆️⬇️ Scroll buttons | Click or hover-hold to scroll the rail; greyed out when there is nothing to scroll |
| 🎛️ Rail mode switch | Settings → General → Turn navigation: DSH official / Smoothly TN (default) / Hide all — persisted across reloads, so the official rail can finally be turned off |
| 🔌 Pure external plugin | No DSH source code modified; no host changes; no new dependencies; no conversation writes (the only DOM writes are an injected style tag, one body class and a transient jump highlight) |
The official built-in TurnNavigator has no off-switch and is always rendered in the chat view. The table below compares it at dsh 0.1.3-alpha.1 (the current DSH web TurnNavigator, which re-added full-session scope via its own host projection) against this plugin, Smoothly TN v0.4.8:
| Capability | DSH official rail (0.1.3-alpha.1) | Smoothly TN (v0.4.8) |
|---|---|---|
| Turns shown | Every turn — host turnOutline projection (0.1.3+) | Every persisted turn — client-side journal read |
| Full-history robustness | Depends on the host turnOutline projection — not driven by browser-synthesized sessions (e.g. ?fixture), where it falls back to the loaded window | Always full — reads the persisted journal directly, no host projection required (verified full on both real and fixture sessions) |
| How full history is read | Host-side turnOutline projection, read by the chat view (the conversation snapshot carries no projection values) | Client pages the persisted journal (session/page); older dsh falls back to sessions.history RPC — zero host changes |
| Jump to a turn outside the window | ✅ (0.1.3+ unloaded anchor pages history by seq) | ✅ on-demand window extension + "Locating turn N…" pulse/bubble |
| Long-session open performance | Reads the projection | Zero prepend — plain data, no flow re-render, no stall |
| Follow-scroll highlight | ✅ (0.1.3+ keeps the active mark in the rail viewport, with a pointer guard) | ✅ (v0.4.1+, same pointer-guarded follow) |
| Hover preview | Prompt (1 line) + response (≤3 lines), no timestamp; a turn with no human prompt shows only its turn number in the prompt line | Turn number + timestamp + prompt (the full first human message for journal-read turns; the host's bounded prompt preview for turns in the loaded window; the turnOutline prompt when neither read one; the localized Turn N last) + response preview (host projection, ≤120 chars — same source as the official rail) |
| Wave ripple animation | ❌ (fixed-pitch ticks widen instead) | ✅ wave ripple |
| Scroll buttons (click / hover-hold) | ❌ (wheel + gradient fade) | ✅ click / hover-hold |
| Rail height | Dynamic band (natural height … 420px) | Auto-sized (≤30vh), internal hidden scrollbar |
| Narrow viewport (<900px) | Auto-hidden | Auto-hidden (mirrors official) |
| Hide / switch rail | ❌ no off-switch | ✅ Settings → General → 3 modes; Hide all hides both |
| Keyboard accessibility | ✅ focus ring + aria-current/aria-busy/aria-describedby | ✅ same pattern: the accessible name is the action (Jump to turn N / Load and jump to turn N for a turn still outside the window) with aria-current/aria-busy, and the preview is linked through aria-describedby → role="tooltip"; tabbing to a capsule shows the preview (no pointer required) |
| Source | Built-in, cannot be disabled | External plugin, can be replaced/disabled |
As of dsh 0.1.3 the built-in rail caught up on full-session scope and out-of-window jumps. What still sets Smoothly TN apart: you can switch it off (the official rail cannot), the tooltip carries the timestamp, the full first human message for turns read from the journal, and the same response preview the official rail shows (falling back to the localized turn number when a turn has no human prompt), there are scroll buttons and wave hover, and it remains an external plugin with zero host changes and no conversation writes. And on dsh ≤ 0.1.2 the built-in rail is simpler still (loaded window only), so the gap Smoothly TN closes is even larger there.
Verified on dsh 0.1.3-alpha.1 (2026-09-06, Playwright against the live web UI): on a real 42-turn session both rails show all 42 turns (the official one via its host projection, ours via the journal); on a ?fixture browser-synthesized session the official rail degrades to the loaded window (24/75) while Smoothly TN still shows all 75 — because our full history never depends on the host projection. Jumps, follow-scroll highlight, the mode switch, and the subtractive takeover of the official rail (display: none via the stylesheet override) all verified working.
Which Smoothly TN release matches which dsh:
| Smoothly TN | dsh | Notes |
|---|---|---|
| v0.1.x | dsh ≤ 0.1.1 | Full history via the legacy sessions.history browser→host RPC |
| v0.2.x – v0.4.1 | dsh 0.1.2+ | Adapted to the ui-chat refactor; full history via the journal session/page channel; v0.4.1 fixed true turn numbers and rail-viewport follow |
| v0.4.2 | dsh 0.1.2+, incl. 0.1.3-alpha.1 | Comparison/positioning updated against the 0.1.3 official rail (see above) |
| v0.4.3 | dsh 0.1.2+, incl. 0.1.3-alpha.1 | This release: brand naming standardized to Smoothly(思磨力)/ Smoothly Turn Nav(Smoothly TN)/ 思磨力轮次胶囊条 — technical IDs (npm package dsh-turn-navigator, plugin/slot IDs, locale namespace, CSS prefix, localStorage key) unchanged |
| v0.4.4 | dsh 0.1.2+, client contract re-checked against 0.1.6-alpha.2 | This release: the official-rail body class gained a dispose hook (disabling or reloading the bundle live from the dsh Plugins page restores the built-in rail), and two stale inject entries are gone |
| v0.4.5 | dsh 0.1.7+ | This release: icon imports follow the 0.1.7 visual-language rename (*Regular stroke variants; rendered sizes unchanged) — the client half requires 0.1.7 from here; v0.4.4 remains the release for 0.1.2–0.1.6 |
| v0.4.6 | dsh 0.1.7+ | This release: the 0.1.7 floor is declared in package.json as an optional peer dependency on @deepseek-ai/dsh-client-ui-conversation (>=0.1.7-rc.1); a host that ships dsh's peer evaluator (0.1.7-rc.1+) can refuse to load a plugin whose floor it does not meet and print the exact dsh plugin allow-version remedy. No behaviour change; runtimes without the evaluator are unaffected — use v0.4.4 on 0.1.2–0.1.6 |
| v0.4.8 | dsh 0.1.7+ | This release: the tooltip gains the response preview (window response → turnOutline.response, matching the official rail's two content lines); a turn without a human prompt no longer shows its number alone |
| v0.4.7 | dsh 0.1.7+ | This release: a turn's tooltip label is no longer fabricated — the data layer keeps an empty label for a machine-woken turn and the tooltip falls back to the localized turn number (official semantics), the journal fold requires an appended human message, and the host turnOutline projection is merged in as the third label source. New behavioural gate scripts/test-turn-labels.mjs (in npm test/verify:all) and live gate npm run verify:turn-labels |
The official-rail comparison in this README targets dsh 0.1.3-alpha.1; on older dsh the official rail is simpler, so Smoothly TN's advantage is larger there. v0.4.6 declares the 0.1.7 floor in package.json (see the version map above). DSH's peer evaluator ships from 0.1.7-rc.1, and every runtime that has it already satisfies >=0.1.7-rc.1 — so the declaration puts the floor in machine-readable form and is what lets a later raised floor be refused by the host with the dsh plugin allow-version remedy; it is not a guard for older runtimes (0.1.6 and earlier, and 0.1.7-alpha.N, ship no evaluator and simply load the bundle), so v0.4.4 remains the release for 0.1.2–0.1.6. The explicit -rc.1 floor is deliberate: >=0.1.7 and ^0.1.7 do not match a 0.1.7-rc.N runtime.
dsh plugin --profile web add dsh-turn-navigator
Then restart dsh web:
dsh web
DSH official (the built-in rail), Smoothly TN (this plugin's rail — default), or Hide all. The official rail has no off-switch, so choosing Smoothly TN hides it with a stylesheet override and our rail takes over the right-edge center position. The choice persists across reloads.The plugin registers two additive slots — no DSH source code is modified:
| Slot | Scope | Role |
|---|---|---|
conversation.session.header.utilities | session | The floating turn rail (renders position: fixed; reads the live chat snapshot via the framework useChat/useSession kit) |
settings.general.item | root | The Turn navigation mode switch in Settings → General |
session/page channel (ctx.remote.session — mounted by the base web assembly; no host changes, no new dependencies). On older dsh it uses the sessions.history RPC. Every turn is derived from raw turn/start / user/message / turn/end events as plain data.loadOlder, with the authoritative hasMore as the loop terminator) until the target is in view — the only path that touches the flow, and it runs only when you click.data-chat-anchor-key, and sets the scrollport's scrollTop directly (more predictable than scrollIntoView).[data-conversation-scroll] nav hide rule still matches. If a future dsh changes that structure, the worst case is the official rail reappearing (side by side) — never a crash.style tag, the tn-hide-official body class (removed on dispose), a transient highlight class on the target row, and the on-demand window extension you trigger by clicking an out-of-window turn.dsh web); developed and verified against dsh 0.1.2+ and verified against dsh 0.1.3-alpha.1 (Playwright re-test, 2026-09-06: full-history rail, jumps, follow highlight, mode switch, and the official-rail stylesheet takeover all passing).conversation.session.header.utilities and settings.general.item slot declarations (present in current DSH).conversation.session.header.utilities and settings.general.item slot declarations, the ui-primitives exports the rail uses, and the --dsw-alias-* tokens it references all still exist. The interactive Playwright re-test was not re-run on 0.1.6 (the 2026-09-06 run remains the last interactive verification).Smoothly TN mode hides the official rail (stylesheet override) and centers our rail in its place; DSH official mode shows the built-in rail instead; Hide all hides both. Both rails auto-hide below 900px width.main slot entry, so the conversation view (and this rail with it) is swapped out rather than layered under.pnpm typecheck — TypeScript check (tsdown does not typecheck).pnpm test — typecheck plus scripts/test-client-dispose.mjs, which loads the built bundle in a DOM stub and asserts the apply/dispose contract of the official-rail body class.pnpm bundle — build the module-table client bundle into lib/.scripts/verify-*.mjs — Playwright acceptance scripts against a live dsh web (rail, full-history journal, mode switch, jump, feedback, overlay, sizing, UI).pnpm release:check — release gates (version, tag, tree, build, registry).MIT
FAQs

Security News
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.

Security News
Anthropic’s free OSS Scanner uses Mythos and other Claude models to find open source vulnerabilities and send maintainers reports with proposed fixes.

Security News
On Front Lines’ Early Adopters: CISO podcast, Andrew Becherer shares lessons from Datadog, weighs the long-term costs of AI-built tools, and explains how founders can actually gain a CISO’s trust.