All plugins

DSH / BUNDLE / CLIENT-UI

dsh-sidebar-pins

v0.1.0AndreyTepaykin / dsh-sidebar-pins92d4e82951

InstallableBundlesUI & client pluginsCommunity · Topic auto-analysisWeb UI

Overview

dsh-sidebar-pins

Pinned-sessions block for the DeepSeek Harness sidebar: a collapsible pinned panel above the Settings row, hover pin buttons on session rows and a session-header toggle. Pins live in the plugin's own settings namespace and are migrated once from dsh-session-pin. Written for DSH 0.1.5-rc.1, where the host-side session reorder no longer reaches the browser-rendered sidebar.

README / EN

Package documentation

Registry summary

Pinned-sessions block for the DeepSeek Harness sidebar: a collapsible pinned panel above the Settings row, hover pin buttons on session rows and a session-header toggle. Pins live in the plugin's own settings namespace and are migrated once from dsh-session-pin. Written for DSH 0.1.5-rc.1, where the host-side session reorder no longer reaches the browser-rendered sidebar.

dsh.pub verifies the pinned bundle contract, runtime facts, and distribution semantics. The complete README remains in the source repository.

Read the full README on GitHub

LIMITATIONS

Known limitations

* **The main list is not reordered.** Pinned sessions live in the panel at the bottom and remain in the regular list: the browser order lives in the core's props-store, which is inaccessible to plugins. * **The panel height is up to `30vh`** (the sidebar occupies the window height), not a fixed number of pixels; if the sidebar is short, the panel yields space rather than squeezing "Settings" off the edge. A collapsed panel (and any panel in rail mode) occupies only the header row. * Session row identification relies on the React fiber (`__reactFiber$…`, React 18) with a fallback to **any nested** `span` with a unique title: with duplicate titles the button will not appear (instead of guessing). The button in the session header does not depend on this heuristic. * **In rail mode there are no session rows in the DOM at all** — there is nothing to mark with a button there, so the 📌 in rows appears when the sidebar is expanded (`rows: 0` in the diagnostics in rail mode is normal, not a failure). * The panel location is derived **only from its own anchor marker** and depends neither on session rows nor on wrappers. The live host adds an extra nameless `div` around the sidebar root and one `div` around each entry of the footer slot, while `footerActions` itself lays out its children **in a row**. Therefore, instead of a fixed chain, the entire path upwards from the anchor is collected, and the location is chosen by measurement: the container must lay out its children in a column (otherwise the panel would lie beside "Settings"), and the panel must end up above the "Settings" row. Levels above the sidebar root are not considered: from there the panel would land above the whole sidebar. The chosen location and the discarded ones are visible in the diagnostics (`seat`, `seatLabel`, `skipped`), and the last resort is the end of the nearest "column" container, that is, the panel stays inside the sidebar. The style node is reinstalled on every pass: a panel without styles would grow to fit its content and squeeze "Settings" off the edge. * The plugin **deliberately imports no external package at all**. With a `link:` install into the profile this is also forced: Node resolves bare imports from the package's real path (the working copy), where there is no `node_modules`, and the entry would fail to load with `ERR_MODULE_NOT_FOUND`. That is why the settings schema is written by hand (see below) — an npm/git install lifts the constraint, but the hand-written schema stays so that behaviour does not depend on how the plugin was installed.