Memory
dsh-turn-outline
Andor-Z/dsh-turn-outline · ★ 2
Turn-outline sidebar tab for dsh-better-sidebar: fold a session into user turns (input + tool steps + output) with structured jump-back into the conversation | DSH 轮次轨迹侧边栏:按用户轮次折叠会话(输入+工具步骤+输出)…
Manifest details
安装
dsh plugin --profile web add 'dsh-turn-outline@0.3.1'从 npm 安装预构建包
For install and environment setup, plus plugin development tutorials, see DSH community docs ↗
README
Table of contents
A DSH plugin: registers a Turn Outline tab in the dsh-better-sidebar sidebar — folds a session into user turns (input + tool steps + output) with structured jump-back into the conversation (works in both the chat view and the trajectory view).
Preview
Real-session screenshot: the whole session folds into turns 1-5, each = user input + tool steps + final output; the tool filter chips at the top (All / bash / read / edit / More) aggregate by semantic dot, and clicking any row jumps back to its place in the conversation.
Overview
Who it is for: users of DeepSeek Harness (Web / Desktop profile) with long sessions who want to quickly revisit "what happened at step N" — at zero cost, without adding an LLM or touching the DSH core.
What it solves:
- Fold the session into user turns — the conversation is collapsed into a structured "input → tool steps → output" trail, so long sessions become scannable at a glance; multi-level folding inside a turn plus tool-type filter chips let you focus on what matters.
- Structured jump-back — click any turn / tool step to auto-load history and scroll to the matching row in the chat view / trajectory view. On 0.2.0 navigation goes through the client
uiConversationconversation view registry (anchorSeqnode matching +loadOlderpaging); on 0.1.x it falls back to the legacy session snapshot — no dependence on DOM text or hashed class names. - Zero AI dependency — pure event folding, no LLM calls: zero tokens, instant open, no failure states.
- Read-only & non-invasive — never touches the DSH core: one read-only host route + one client tab; registers cleanly and unloads without residue.
- Incremental performance — refreshes are driven by session subscriptions (no polling);
TrailFolderonly re-folds open turns (O(delta)); seq-keyed rows reconcile in place instead of remounting.
💡 Complements dsh-conversation-outline: that plugin generates a one-line LLM title per turn ("conversation outline"); this one is LLM-free and folds the raw "turn trail". Both register distinct tabs and can be used side by side from better-sidebar's + menu.
Install
Prerequisite: a DSH plugin host + dsh-better-sidebar. This plugin declares better-sidebar as an optional peer — without it the plugin still loads, it just does not register the tab (inert, no side effects).
Option 1: one-liner from npm (recommended)
Install better-sidebar first, then this plugin:
npx @deepseek-ai/dsh plugin --profile desktop add dsh-better-sidebar
npx @deepseek-ai/dsh plugin --profile desktop add dsh-turn-outline
Using the Web profile? Swap
--profile desktopfor--profile web.ℹ️ Version-line note: since 0.3.0 the primary line is DSH 0.2.0-rc.x (tested against the DSH Desktop 2.0.17 bundled runtime + better-sidebar 0.24.1; jump-back rides the
uiConversationconversation view registry and the host live path usessnapshotEvents()). The 0.1.x lines stay fallback-compatible — better-sidebar 0.18.0 + DSH 0.1.2-rc.1 and better-sidebar 0.17.1 + DSH 0.1.1-rc.x (stable): on older hosts the plugin automatically uses the legacy snapshot jump and the.eventslive path, with no configuration. Note that better-sidebar 0.18.0 supports only DSH 0.1.2-rc.1+: on an older stable host (0.1.0-rc.8 ~ 0.1.1-rc.2), pindsh-better-sidebar@0.17.1.
Option 2: install from source (development / offline)
git clone https://github.com/Andor-Z/dsh-turn-outline
cd dsh-turn-outline
pnpm install && pnpm build && pnpm pack # produces dsh-turn-outline-0.2.6.tgz
npx @deepseek-ai/dsh plugin --profile desktop add "file:$(pwd)/dsh-turn-outline-0.2.6.tgz"
Restart & enable
Restart DSH (host-side changes need a full restart; client-side changes only need a hard refresh Cmd/Ctrl+Shift+R). Open better-sidebar's + menu and pick Turn Outline.
Uninstall
npx @deepseek-ai/dsh plugin --profile desktop remove dsh-turn-outline
Quick start
- Install as above and restart DSH.
- Open any session and add Turn Outline from better-sidebar's + menu.
- The trail is folded by user turn; click any turn / tool step to jump back to its exact position in the conversation (chat view and trajectory view both supported).
- Use the turn / tool filter chips to collapse what you do not need.
Architecture
host (Node) inject: ['webServer','sessionQuery','sessions']
POST /turn-outline/api/events { sessionId, afterSeq }
→ live sessions: borrow the frozen snapshot of the live store (snapshotEvents() on DSH
0.2.0, the .events property on 0.1.x; O(1) probe + O(delta) projection, zero deep clones)
→ cold sessions: sessionQuery persisted log + lastSeq cache (LRU + byte cap)
→ paged responses (PAGE_SIZE events per page, hasMore semantics) + field trimming (no full tool-result payloads)
→ 200 { events, hasMore } / 400 / 403 / 404 / 405 / 413
client (browser) inject: ['sessions','uiConversation','betterSidebar'] (the latter two are optional peers)
→ registerTab({ id:'turn-outline', single:true, description })
→ jump-back: on 0.2.0 the ctx.uiConversation conversation view registry (chat/trajectory
targets); on 0.1.x the legacy session snapshot's chat.nodes / views fields
→ subscription-driven refresh (session.subscribe + the 0.2.0 eventSource; no polling)
+ incremental folding (TrailFolder: only re-folds open turns)
+ seq-keyed rows (append without remount) + per-turn React.memo + three-level folding + tool filter chips
Performance design (introduced in v0.2.1)
- No more deep-cloning the whole log on the host: the old
listEventsprobe andreadSessionread eachstructuredCloneevery event (~3 full deep clones per request for live sessions). Live sessions now borrow the store's frozen event snapshot directly (snapshotEvents()on 0.2.0 / theeventsproperty on 0.1.x — the cached, immutable array is reused): O(1) probe, O(delta) incremental reads, fully synchronous, zero copies. - Paged + trimmed responses: at most
PAGE_SIZEevents per page (hasMorepulls the rest; first paint renders progressively); events project only the fields folding needs (text capped atTEXT_CAP, arguments atARGS_CAP,tool/resultkeeps only the error field — the largest transfer/memory cost is gone). - Incremental client folding:
TrailFolder.push()consumes each event exactly once;snapshot()reuses the TrailTurn objects of already-sealed turns (stable identity →React.memore-renders only open turns), turning each refresh from O(n) full refolds into O(delta); duplicate/re-sent pages are dropped by the seq watermark. - Rows keyed by seq: appended steps reconcile in place in the DOM instead of shifting indexes and remounting whole chunks.
Permissions & data
- Session logs: one read-only host route
POST /turn-outline/api/events, browser same-origin + Host-header trust fence; read-only, never writes or mutates the session. - Zero LLM calls: nothing is sent to any model; no token consumption.
- No credential access: no other network/file access besides session events; no user config, no persistent storage (tab state follows better-sidebar's layout persistence).
Compatibility
| Item | Value |
|---|---|
| Platform (primary) | DSH 0.2.0-rc.x (tested against the DSH Desktop 2.0.17 bundled runtime; web/desktop profile) |
| Platform (fallback-compatible) | DSH 0.1.2-rc.1 / 0.1.1-rc.x (stable line) |
| Dependencies | dsh-better-sidebar (optional peer, >=0.17.0; inert when absent), react (injected by the DSH client seed) |
| Build | TypeScript + esbuild, no runtime npm dependencies |
| Tests | vitest, 100 cases (fold / folder / jump / tab / host) |
Development
pnpm install # if pnpm 10+ blocks build scripts, allow esbuild as prompted (see pnpm-workspace.yaml)
pnpm typecheck # tsc --noEmit
pnpm test # vitest run (100 cases)
pnpm build # esbuild → lib/index.js + lib/client.js (includes bundle-contract self check)
pnpm pack # produces dsh-turn-outline-<version>.tgz (prepack rebuilds automatically)
Layout: src/index.ts (host route) / src/client/ (tab + folding model) / tests/ (vitest + jsdom).
Contributing: fork → change → pnpm typecheck && pnpm test && pnpm build → open a PR.
Troubleshooting
| Symptom | Meaning / fix |
|---|---|
| No "Turn Outline" in the + menu | Make sure better-sidebar is installed and on 0.17.x, and the plugin is in the profile (dsh plugin --profile desktop list); a full DSH restart is required after host-side changes |
| Page errors / broken styles | Client change not hard-refreshed yet: Cmd/Ctrl+Shift+R |
| No trail for a cold session | Generate any new event in the session (or activate it) before opening the tab; the read-only route only replays persisted logs |
| Plugin update not taking effect | Host-half changes need a remove + add reinstall (same-version reinstalls can be skipped by the pnpm cache, see Option 2) |
| Marketplace update still shows the old version | The dshmarket install path enforces a 24h release-age cooldown (supply-chain protection); versions published less than 24h ago are silently skipped (exit 0, no error). Wait 24h, or install immediately from the CLI: npx @deepseek-ai/dsh plugin --profile desktop add dsh-turn-outline@<version> |
License & security
MIT. For security issues, report privately via Issues, or contact the author by email before public disclosure.