Pin sessions and workspaces to the top of the Web sidebar with per-pin row colors, a header toggle and a pinned panel; 0.4.0 adds a navigation organizer — pin groups (boards), tags and saved filter views, session health summaries, and /goto.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-session-pin
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:PerryLink/dsh-session-pin
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
📌 dsh-session-pin
- 1024 store channel:
npm i -g dsh1024once, thendsh1024 plugin --profile web add dsh-session-pin(counts toward the deepseek1024.com install ranking).
Pin sessions and workspaces to the top of the DeepSeek Harness sidebar with per-pin row colors.
A dual-face (host + browser) plugin: two pin levels, an 8-color swatch per pin, and a navigation organizer — boards, tags, saved views, health summaries, and /goto.
Official repository. This is the only official repository of dsh-session-pin, maintained by PerryLink. Same-name repositories under other accounts are not affiliated.
English · 简体中文 · Español · Português · हिन्दी
⭐ 如果它帮到了你
这个插件是 DSH 插件家族的一员(40+ 个,全部 Apache-2.0)。如果你在用,给个 star —— 它不会解锁任何功能,但会让下一个人在搜索里更容易找到它。
English: part of a 40+ plugin family for DeepSeek Harness. If it is useful, a star helps the next person find it — nothing is gated behind it.
Compatibility
| Surface | Status |
|---|---|
| Harness | DeepSeek Harness dsh-v0.1.7-rc.2 (GitHub tag; verified 2026-09-22: dual-ruler typecheck + unit/composition suites + static seam checks; browser pass pending maintainer). npm dependency line 0.1.7-rc.2, peers >=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0 || >=0.1.6-0 <0.2.0 || >=0.1.7-0 <0.2.0. |
| Node | >= 22 (development floor) |
| Platforms | Web GUI (dual-face: host + browser) |
| Model | Any (UI-only — no model traffic, no session events) |
session/pin events |
Pre-flight-gated: written only when the host's runtime event vocabulary knows the type (the alpha-line append can no longer stamp the ignorable marker, so the vocabulary is the single gate signal — adapted 2026-09-18); otherwise the projection degrades to the settings cache and one warning fires before the first write. |
What you get
dsh-session-pin keeps the conversations that matter at the top of the sidebar and colors them so you can find them at a glance:
- Two pin levels — pin whole workspaces and individual sessions; a pinned workspace moves to the front of the workspace list and a pinned session to the front of its account.
- Per-pin row colors — a swatch after each pin cycles an 8-color preset palette (Shift+click clears); the row gets a left accent bar plus a translucent tint.
- Four pin surfaces — a hover
[pin][swatch]pair on every row, a pin toggle in the session header, a sidebar foot action with a pinned panel, and per-browser durable pinning that keeps pins and colors across restarts. - Click-to-open — clicking a pinned row in the sidebar or the pinned panel opens the session in the current window (the same seam
/gotouses); both navigate through the host's session-retain channel on the alpha line. - Zero core changes — a standalone plugin for the stock DSH Web GUI; every surface degrades gracefully on older baselines.
┌─ Workspaces ────────────────────────────┐
│ 🎨 Workbench ███ │ ← pinned workspace, tinted red
│ 📌 Implement login flow 3h │ ← pinned session, tinted teal
│ Fix the auth bug 1h │ ← hover shows a gray pin + swatch
│ Refactor the DB layer 2d │
└─────────────────────────────────────────┘
Navigation organizer
Four browser-local capabilities organize multi-session work on top of pinning. All state rides the same session-pin store (per-browser; nothing is uploaded), and each has a Config switch.
- Boards — pins join named groups; the board chip row creates, renames, and deletes boards and drag-reorders them (order persists per-browser), while the pinned panel groups each board's pins under a collapsible header.
- Tags & views — entities carry up to 8 tags (≤24 chars each), set per row from the panel's manage button (which also assigns the pin's board); the filter bar matches text and tags, and any filter state saves as a named view (up to 20) for one-click switching.
- Health summary — each pinned session row appends a read-only, sanitized line (
N msgs · you|ai · relative time) derived from the public session snapshot — counts and directions only, never content. /goto <keyword>— a composer line starting with/gotoplus Enter jumps: a unique title/tag match opens it, several matches list in a prompt, none explains. The command line never reaches the model.
How it works
- Host half (
src/index.ts) — declares thesession-pinsettings form as the plugin's own live Config: the two pinned id lists, the two color maps, the organizer state, and the host policy (maxPins/reorderOnLoad/pruneStaleplus the five feature switches) are all.volatile()fields. On the0.1.7settings contract a form's namespace is the local id of its profile entry, so the bundle patch'sid: session-pinrow names the form, the Plugins page edits it, and accepted edits are hot-applied to the running plugin; no session events, no model traffic. - Browser half (
src/client.ts) — assembles a framework-freePinStore(the host half's live Config form read throughctx.configForms.get(entryId), degrading to a versionedlocalStoragedocument with cross-tab sync), aPinController(two-level toggle / color cycle / prune / reorder state machine), and the UI: the row overlay, the optional row-slot registration, the header toggle, the sidebar foot action, and the pinned panel. Ordering goes throughctx.workspaces. - Log-backed write channel — on builds mounting the built-in
dsh-session-pinservice, every session toggle commits through thesession.setPinnedRPC first (thesession/pinevent log is the canonical residence) and mirrors the commit into the settings store; a failed or slow RPC degrades to a direct settings write. - Log-backed projection read —
enableLogBacking(host Config, fail-closed default off) mounts a projection reader that folds livesession/pinevents into the canonical pin set and mirrors the foldedpinned/colorsinto the live Config, which becomes the idempotent cache for the log-backed state. The event schema, the pure fold (foldPinEvents), and the pre-flight-gated append seam (PinLogAppender) live insrc/pin-log.ts: the host's runtime event vocabulary alone gates the write BEFORE the first append (the alpha-line append can no longer stamp theignorablemarker, so the old marker probe is gone), so hosts that cannot safely carry the event — a vocabulary that does not know the type fails closed on read — never receive one; the live Config/localStorage store remains the compat + degradation path. - Client seam — the browser half reads
SessionId/WorkspaceIdbrands from@deepseek-ai/dsh-client-connection(the removeddsh-client-runtimepackage no longer exists on current hosts); the session-header slot's standard-kit seats are typed as a local structural contract. On0.1.2-rc.1hosts thesessions.row.actionrow slot is not declared, so session rows fall back to the DOM overlay and the row-slot registration stays deferred. - Build — esbuild emits the host ESM half and the client CJS half wrapped in the web boot factory (
window.__ModuleLoader__.load({ id, factory }));reactis externalized onto the shell's own React, and a purity gate fails the build if any@deepseek-ai/*value import leaks into the browser bundle.
Extension points used: settings (host); sessions, workspaces, configForms, connection, slots (client); locale (client, optional); conversation.session.header.actions, sidebar.footer.action, shell.overlay, and the upstream sessions.row.action row slot when declared (0.1.2-rc.1 hosts do not declare it — the DOM overlay covers session rows there). Model-visible effects: none — this is a UI-only plugin: it adds no session events and no tokens to any model request.
Quick start
# 1. install the bundle into your profile
dsh plugin --profile web add "github:PerryLink/dsh-session-pin#main"
# or from npm (published releases)
dsh plugin --profile web add dsh-session-pin
# 2. restart and verify the row
dsh --profile web --dump-config | grep -A3 'id: session-pin'
Loader entry id. On harness builds whose
dsh-basebundle mounts the built-in host service@deepseek-ai/dsh-session-pin(entry idsession-pin), give this plugin a distinct entry id such asid: session-pin-uiin the profile patch row — a duplicatesession-pinid fails the boot with "duplicate loader entry id".
Install & uninstall
- git channel (latest
main):dsh plugin --profile web add "github:PerryLink/dsh-session-pin#main"—pnpm run buildemits the host half (lib/index.js) and the browser half (lib/client.js). - npm channel (published releases):
dsh plugin --profile web add dsh-session-pin. - tarball channel:
pnpm packin this repo, thendsh plugin --profile web add ./dsh-session-pin-<version>.tgz. - uninstall:
dsh plugin --profile web remove dsh-session-pin(or remove the row from the profile patch — the row IS the settings form namespace, so removing it also removes the stored form values).
Configuration
All tunables are Schemastery Config fields. Every field below is .volatile(), so it is editable live from the profile's Plugins page as well as from cordis.yml (an accepted edit is committed into the running plugin without a remount); pin lists, color maps, and organizer state are the same kind of field, which is what makes the browser half's store durable. enableLogBacking is deliberately NOT volatile: it was never part of the editable surface and no browser half reads it. cordis.patch.yml mounts the bundle with the defaults below.
| Key | Default | Meaning |
|---|---|---|
maxPins |
0 |
Maximum pinned entities per level (sessions and workspaces each have their own budget); 0 = unlimited |
reorderOnLoad |
true |
Re-assert the pinned prefixes (newest pin first) once the lists are ready |
pruneStale |
true |
Drop pins and colors for entities absent from a ready list (deleted/archived) |
enableBoards |
true |
Enable pin groups (boards) in the sidebar panel |
enableTags |
true |
Enable session/workspace tags and the panel filter bar |
enableViews |
true |
Enable saved filter views |
enableHealth |
true |
Enable the per-pinned-session health summary (read-only, sanitized) |
enableGoto |
true |
Enable the /goto <keyword> composer command |
enableLogBacking |
false |
Fold session/pin events into a log-backed projection and mirror it into the settings cache (fail-closed: the session log is canonical when enabled) |
Tools & surfaces
| Surface | Kind | Notes |
|---|---|---|
[pin][swatch] row controls |
UI slot / DOM overlay | Hover controls on every session and workspace row |
| Session header toggle | UI slot | The same pin control in the header action row, keyed by session id |
| Sidebar foot + pinned panel | UI slot / overlay | Lists pinned workspaces and sessions, grouped by board (collapsible) with per-row board/tag manage and color dots |
/goto <keyword> |
command | Composer quick-jump by title/tag; the line never reaches the model |
session-pin settings form |
host service | The plugin's own live Config, durable per profile: pins, colors, and organizer state |
Permissions & data
- Permissions: the
dshWorkshopmanifest declaresbrowser:local-storage,settings:read, andsettings:write. - Data: pins, colors, and organizer state live in the plugin's
session-pinsettings form (thepinned/workspacePinned/colors/workspaceColors/boards/tags/viewsvolatile Config fields), degrading to a versionedlocalStoragedocument (v1 documents migrate) where the web proxy does not serve the entry. Nothing is uploaded. WithenableLogBacking, the live Config becomes the idempotent cache for the log-backedsession/pinprojection. - Session log: none by default — this plugin adds no session events and no tokens to any model request. When
enableLogBackingis on, the host folds the log-onlysession/pinevent (written by the upstreamsession.setPinnedRPC) into the canonical pin projection;PinLogAppenderpre-flight-gates its own writes on the runtime event vocabulary, so hosts that cannot carry the event never receive one. Model-visible effects remain none.
Security boundaries
- UI-only. No model-visible effects, no network, no subprocesses; every surface degrades gracefully on older baselines.
- Durable, bounded state. Pins and colors are pruned with deleted entities (
pruneStale);maxPinscaps the pinned count per level. - Read-only health. The health summary derives counts and directions from the public session snapshot and writes nothing back.
Known limitations
- Persistence scope — the log-backed canonical residence is opt-in (
enableLogBacking, fail-closed default off) and its live read loop requires builds that emit thesession/pinevent (the upstreamsession.setPinnedRPC); on baselines without it, pins and colors fall back to the plugin'ssession-pinsettings form, then to browser-locallocalStorage. On hosts whose event vocabulary does not know the type, the pre-flight gate disables log appends entirely (the fail-closed read path would reject such logs), so the projection degrades to the settings cache there. - Ordering scope — the pinned position is stable only under Manual order; under Updated order the core's activity promotion re-fronts active sessions, and
reorderOnLoadre-asserts the prefixes on load. - Remote browsers — settings RPCs are loopback-only on the baseline; remote browsers fall back to browser-local
localStorage. - Row badge fallback — where the upstream row slot is unavailable, session 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"structure and must follow upstream UI changes.
Roadmap
Canonical residence: a log-backedLanded (P0): the plugin ships thesession/pinevent +pinprojection + write RPC (upstream) — the settings namespace then retires as the durable store and the plugin consumesuseProjection('pin').session/pinevent schema, the pure projection fold (foldPinEvents), the pre-flight-gated append seam (PinLogAppender), and a host projection reader (enableLogBacking) that folds livesession/pinevents back into the live Config cache. The live Config/localStorage store remains the compat + degradation path; the log is canonical when enabled.- Self-build write fallback: wire
PinLogAppenderto appendsession/pinevents on builds without the upstreamsession.setPinnedRPC, so no-upstream baselines also log canonically. - Consume the upstream
pinprojection (useProjection('pin')) on the client once@deepseek-ai/dsh-session-pinships in the npm baseline; today the host mirror covers the read path on master builds. - Right-click / row-menu "Pin" entry (needs a core row-level menu slot; the row badge slot is upstream now).
- A full color-picker popover (custom colors) once the canonical residence exists; today's cycle swatch covers the preset palette.
Development
pnpm install # install dependencies
pnpm run typecheck # tsc --noEmit
pnpm test # vitest unit tests
pnpm run build # dual-half build + client-bundle purity check
node scripts/verify-live.mjs # live check against a running `dsh web` (DSH_CHECKOUT env)
Topics
deepseek-harness, dsh, dsh-plugin, session-pin, pin, workspace
Contributors
- @PerryLink — creator and maintainer: pin UX, durable persistence, workspace ordering, per-pin row colors, the navigation organizer, and the five-language docs.
PerryLink DSH Plugin Family
This project is one of the 45 DeepSeek Harness plugins maintained by PerryLink. If this one helps you, the others likely will too:
| Plugin | One-liner |
|---|---|
| dsh-auto-review | Second-model auto-review on the approval chain, fail-closed by default |
| dsh-autotier | Automatic strong/cheap model-tier routing with deterministic risk guards and a /tier command |
| dsh-background-agents | Durable background child agents with a Web UI sidebar, messaging and interrupt |
| dsh-budget | Cost governance for DeepSeek Harness: budgets, carbon, and latency in one panel. |
| dsh-catalog | DSH Desktop Market standard catalog source for the PerryLink family |
| dsh-cert-mcp | Read-only MCP server exposing the certification registry: grades, snapshots and five-dimension evidence |
| dsh-checkpoint-rewind | Claude Code /rewind-equivalent: snapshots, session forks, one-shot restore |
| dsh-claude-move | Migrate Claude Code sessions, memory, skills and CLAUDE.md into DSH |
| dsh-click | Cross-platform native desktop control for DeepSeek Harness — Windows first. |
| dsh-composer-history | Terminal-style input history for the web composer: arrows, Ctrl+R search |
| dsh-data-quality | Dataset quality checks and citation cross-checks (the optional numeric bridge consumed here) |
| dsh-defend | Prompt-injection, jailbreak, and secret-leak defense for DeepSeek Harness. |
| dsh-doublecheck | Engineering-discipline guard: requirements grill, test gates, adversary review |
| dsh-draw | Unified static-image generation routing for DeepSeek Harness. |
| dsh-fast | Read-only performance diagnostics for DeepSeek Harness. |
| dsh-fund-research | Deterministic research reports for Chinese public mutual funds |
| dsh-github | GitHub PR/issues integration for DSH, every write gated by approval |
| dsh-industry-research | Industry research orchestration that seals its deliverables through this plugin's ctx.researchReport.assemble |
| dsh-laya | Laya typed decisions (noul/choice/score) as a first-class Cordis service and model-visible tools |
| dsh-library | Local document knowledge base for DeepSeek Harness. |
| dsh-local-ai | Local-model (Ollama) integration for DeepSeek Harness. |
| dsh-lsp-actions | LSP diagnostics, formatting, completion, code actions and rename over language servers |
| dsh-mask | PII masking middleware: anonymize at the model boundary, restore at the display layer |
| dsh-mcp-panel | Read-only MCP runtime panel: /mcp command + Settings tab with status, tools and errors |
| dsh-memento | Approval-gated cross-session memory: ctx.memory seam + SQLite + memory tool |
| dsh-observe | OpenTelemetry and Langfuse observability exporter for DeepSeek Harness. |
| dsh-output-styles | Claude Code outputStyles-equivalent runtime style switching |
| dsh-permission-rules | Claude Code-style declarative allow/deny/ask permission rules with audit |
| dsh-plugin-certification | Community certification registry with repro-checkable grades and badges |
| dsh-plugin-doctor | Zero-dependency static + sandbox smoke detector for DSH plugins |
| dsh-plugin-guide | Plugin-development knowledge base as an on-demand agent skill |
| dsh-plugin-kit | Shared zero-runtime-dependency toolkit for the PerryLink DSH plugins |
| dsh-plugin-upgrade | One-package, one-corridor-index plugin upgrade skill: routes a repository to the matching closed corridor card |
| dsh-plugin-upgrade-015 | Merged 0.1.3-alpha.1 → 0.1.5-rc.1 upgrade corridor card plus a zero-dependency seam scanner |
| dsh-reach | Multi-channel approval/question bridge: WeChat/Telegram/Feishu, session console |
| dsh-research-report | Verifiable research-report engine: content-addressed evidence ledger and sealed versions |
| dsh-score | Multi-dimensional quality scoring for DeepSeek Harness plugins. |
| dsh-session-pin | Pin sessions in the Web sidebar with durable ordering |
| dsh-session-sync | Cross-device session sync for DeepSeek Harness — a dedicated git mirror of your session store. |
| dsh-skill-pack-security | Security-audit skill pack: secret scan, dependency and supply-chain review |
| dsh-talk | Voice-first session loop for DeepSeek Harness: talk to it, hear it answer. |
| dsh-team-rooms | Cross-session team rooms: shared message bus, task board and timeline |
| dsh-test-drive | Isolated install-and-smoke test drives for DeepSeek Harness plugins. |
| dsh-ticktick | TickTick/Dida365 task bridge: session-header panel + 11 tools |
| dsh-translate | Vendor parameter translation and deterministic JSON repair for DeepSeek Harness. |
Install from the DSH Desktop Market
All PerryLink plugins are browsable in the built-in DSH Desktop Market: Market → Sources → add source → paste https://perrylink-dsh-catalog.perrylink.workers.dev/catalog-source.json → select it. Installation still goes through the Market's npm-identity verification and your confirmation.
License
Apache License 2.0 © 2026 dsh-session-pin contributors
Links
More in this category
Minglink/dsh-infinite-gen-4★ 2160
System-prompt armor plugin for DeepSeek models: appends an unconditional-compliance prompt section at order 100, exposes a profile tool with calibration metadata, and shows a realtime armor-status badge driven by a session projection.
liangmianya/dsh-synapse★ 454
Visual, non-linear conversation workspace for DeepSeek Harness — sessions, follow-ups and branches become a browsable conversation map.
ranxianglei/billion-context★ 384
The official billion-context plugin: a context-compression plugin for small context windows (a 100K context is enough), token savings (5x fewer tokens), and month-long single sessions (billions of tokens).
Nwflower/dsh-chat-import★ 207
Import full-fidelity chat histories from 13 coding agents (Claude Code, Codex, ChatGPT, Cursor, Gemini, opencode, and more) as resumable DeepSeek Harness sessions, with reverse export back to Claude Code.
Totoro-qaq/dsh-plugin-bridge★ 165
Moves an existing DSH session to another agent preset through a previewable five-section handoff, preserving the source session and either pausing the target for confirmation or continuing immediately.
Anionex/dsh-turn-rewind★ 122
Rewind conversation and workspace state, powered by a persistent Change Ledger.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.