DSH Plugin Store
← Back to home

PerryLink

dsh-session-pin

Pin sessions in the DeepSeek Harness (DSH) web sidebar - dual-face plugin with a hover pin badge, durable pinning, and top ordering

Stars
1
Language
TypeScript
Created
Aug 13, 2026
Updated
Aug 14, 2026
Web UI
GitHub repo

Introduction

πŸ“Œ dsh-session-pin

English Β· δΈ­ζ–‡ Β· EspaΓ±ol Β· PortuguΓͺs Β· ΰ€Ήΰ€Ώΰ€¨ΰ₯ΰ€¦ΰ₯€

License: Apache-2.0 Topic: dsh-plugin DSH baseline: 0.1.0-rc.6 GitHub stars

Pin the conversations that matter. A dual-face (host + browser) plugin for DeepSeek Harness that puts a one-click pin badge on every session row β€” gray on hover, amber while pinned β€” moves pinned sessions to the top of their workspace group, and keeps the pin across restarts and browsers.

Why pinning?

Session lists sort by recency: the conversation you rely on all week slowly sinks to the bottom, and every new chat buries it further. Dragging rows in the Manual sort mode works, but nobody discovers it β€” and pinned chats that still get re-sorted on activity are exactly what users of other coding agents complain about. dsh-session-pin gives you the one-click UX instead:

β”Œβ”€ Sessions ──────────────────────────────┐
β”‚ πŸ“Œ Implement login flow         3h      β”‚  ← pinned: amber pin, always visible
β”‚   Fix the auth bug              1h      β”‚  ← hover shows a gray pin to toggle
β”‚   Refactor the DB layer         2d      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“Έ Demo

Hover a session row to reveal the gray pin; click to pin β€” amber and pinned on top, still pinned after a reload. (Real screenshots from a live dsh web run.)

Gray pin badge on row hover Amber pin badge while pinned

✨ Features

  • 🧷 Hover pin badge β€” a gray pushpin fades in at the left of the session title on hover; pinned sessions keep a solid amber pin. One click toggles, and the click never opens the session.
  • πŸ“Œ Top ordering β€” pinning moves the session to the front of its workspace account via the public workspace.insertSessionBefore RPC. Under the core's Manual order the position stays put β€” no activity re-sorting.
  • πŸ’Ύ Persistent pinning β€” the host half registers the durable session-pin settings namespace; the browser half writes through the standard settings.* RPCs. On current DSH builds the web proxy serves only its allowlisted namespaces, so until that allowlist moves to settings.register() (upstream deferred work) the browser half falls back to localStorage β€” pins survive reloads in the same browser either way.
  • πŸ”’ Optional limit β€” config.maxPins caps the pinned count (default 0 = unlimited); exceeding it is rejected with a log line.
  • 🧩 Zero core changes β€” a standalone plugin for the stock DSH Web GUI; no patched harness required.
  • 🌍 Five languages β€” English Β· δΈ­ζ–‡ Β· EspaΓ±ol Β· PortuguΓͺs Β· ΰ€Ήΰ€Ώΰ€¨ΰ₯ΰ€¦ΰ₯€.

πŸš€ Quick start

  1. Install β€” add the plugin to your profile's cordis.yml:
plugins:
  '@dsh-external/dsh-session-pin':
    path: /path/to/dsh-session-pin
    config:
      maxPins: 5      # optional; 0 = unlimited (default)
  1. Build (the web app refuses to start with a missing client bundle):
pnpm install
pnpm run build      # lib/index.js + lib/client.js
  1. Restart dsh web and hover any session row in the sidebar β€” the pin badge appears at the left of the title. Click to pin.

Uninstall β€” remove the plugin row from cordis.yml and restart. The session-pin section can also be removed from settings.yaml; nothing else is written.

βš™οΈ Configuration

KeyTypeDefaultMeaning
maxPinsinteger0Maximum pinned sessions; 0 = unlimited. Unpinning always works.

🧠 How it works

  • Host half (src/index.ts) β€” registers the session-pin settings namespace ({ pinned: string[], maxPins }). No session events, no model traffic.
  • Browser half (src/client.ts) β€” binds the namespace through ctx.settingsScope, renders badges over the core session rows, and orders through ctx.workspaces. A MutationObserver re-applies badges after React re-renders; rows are identified by [role="treeitem"][aria-selected] plus title text (no row-level extension slot exists for third-party plugins yet).
  • Build β€” esbuild emits the host ESM half and the client CJS half wrapped in the web boot factory (window.__ModuleLoader__.load({ id, factory })), with a purity gate that fails the build if any @deepseek-ai/* value import leaks into the browser bundle.

Extension points used: settings (host), sessions / workspaces / settingsScope / connection / remote (client). Model-visible effects: none β€” this is a UI-only plugin: it adds no session events and no tokens to any model request.

πŸ“¦ Compatibility

LayerBaseline
DeepSeek Harnesssnapshot 0812 / npm @deepseek-ai/dsh@0.1.0-rc.6 generation (client packages 0.1.0-rc.6)
Cordis peer@deepseek-ai/cordis: ^4.0.1
Node (dev)β‰₯ 22

πŸ§ͺ Development

pnpm install
pnpm run typecheck  # tsc --noEmit
pnpm run test       # vitest unit tests
pnpm run build      # dual-half build + client-bundle purity check

πŸ—ΊοΈ Roadmap

  • Right-click / row-menu "Pin" entry (needs a core row-level slot or a menu overlay).
  • Standalone Pinned section at the top of the sidebar, Slack-Starred-style β€” informed by how Cursor, Claude, Slack, Notion and Telegram all converge on a dedicated pinned block.
  • Canonical residence: a log-backed session/pin event (the session/title pattern) once a client-readable projection channel exists.

⚠️ Known limitations

  • Persistence scope β€” on the current DSH baseline the session-pin settings namespace is not in the web proxy's served-allowlist, so the browser half stores pins in localStorage (browser-local) until upstream exposes plugin namespaces. The host-side namespace registration is already in place and becomes the durable store automatically once that lands.
  • Ordering scope β€” the pinned position is stable only under Manual order; under Updated order the core's activity promotion re-fronts active sessions. Ungrouped and flat-list views have no host-side account, so position is not persisted there (badges and pin state still work).
  • Remote browsers β€” settings RPCs are loopback-only; remote browsers fall back to browser-local localStorage.
  • Duplicate titles β€” rows are matched by title text; with duplicate titles the badge shows on every matching row and toggles the first match (cosmetic).
  • Row DOM dependency β€” the overlay relies on the core rows' role="treeitem" / aria-selected structure and must follow upstream UI changes.

🌐 Community

πŸ“œ License

Apache License 2.0 β€” see LICENSE. Copyright Β© 2026 dsh-session-pin contributors.