# dsh-apes-sidebar
> [!IMPORTANT]
> **Built on DSH's native sidebar API** (since v0.19.0): the right column *is* DSH's own sidebar β the plugin registers every tab type as a native tab (no right panel of its own anymore) and keeps only its self-drawn bottom workbench and the `ctx.betterSidebar` service open to every plugin.
>
> **Since v0.24.1 the host support floor is DSH `0.2.0-rc.1+`** (peer floor `^0.2.0-rc.1`). Everything this plugin consumes from 0.2.0 is **purely additive** (zero removed exports, session format still v4, CLI and client runtime byte-identical), so this version carries no runtime compatibility branch β it only moves the support line. **Hosts on the 0.1.7 line should pin `dsh-apes-sidebar@0.22.1` β a caret never spans a minor bump, and `^0.1.7-rc.1` is silently disabled by the 0.2.0 startup preflight**; the DSH-to-plugin version table is in [Installation](#-installation).
## π Contents
- [β¨ Features](#-features)
- [π Installation](#-installation)
- [πΌοΈ Feature Tour](#-feature-tour)
- [π¬ Community](#-community)
- [π Recent Updates](#-recent-updates)
- [β¨οΈ Keyboard Shortcuts](#-keyboard-shortcuts)
- [π Service API](#-service-api)
- [π οΈ Development & Build](#-development--build)
- [π Security](#-security) Β· [β οΈ Known Limitations](#-known-limitations) Β· [π₯οΈ Platform Support](#-platform-support)
- [π Plugin Ecosystem](#-plugin-ecosystem) Β· [π€ Contributing](#-contributing) Β· [π₯ Contributors](#-contributors) Β· [π Friends](#-friends)
## β¨ Features
What this plugin adds on top of DSH's stock sidebar:
- **βοΈ Editable editor**: the host's document preview is **read-only** β the plugin keeps an **editable** CodeMirror editor (save, syntax highlighting, preview toggle); Markdown / HTML also render through the plugin's own pipeline (Mermaid diagrams with safe rendering + click-to-zoom, README-level inline HTML, floating table of contents, sandboxed HTML preview)
- **ποΈ Enhanced file tree**: takes over the built-in Files page β lazy-loading tree, **expanded directories watched live and auto-refreshed**, symlink awareness, global filename search, drag-and-drop upload, hover `@file` to drop a reference into the input box; **Ctrl/Cmd multi-select and Shift range-select** (copy or delete a batch), **VS Code-style git status colors + M/A/D/U letters**, **new folder**, **multi-select βZip and downloadβ** (the host streams a ZIP built with no third-party dependency), and an βOpen withβ menu that COMBINES DSHβs own open-in-app (the hostβs probed OS handlers + file-manager reveal) with the pluginβs own targets (file manager / VS Code / Cursor / Zed / custom editor URL templates, SSH remotes, pin-to-menu)
- **πΏ Changes** (no Git panel in the stock sidebar): two lenses in one tab β **Git** (diff / history / stageΒ·commitΒ·revert) and **This Session** (every file the model touched) β with a unified diff renderer (intra-line character highlights, syntax coloring, secret redaction); the two lenses now share one 36px header (host SegmentedControl), 28px rows, a single empty state and a sticky commit bar, and the git snapshot is shared with the file tree so staging recolors the tree too
- **π§© Background Tasks** (absent upstream): agent topology preview + background task list (exit codes / live output / force-kill)
- **π¬ Side Chat** (absent upstream, beta): Codex-style side threads β inheriting the full parent context, running independently, promotable to a top-level session
- **π₯οΈ Bottom workbench** (absent upstream): the right column belongs to DSH's native right sidebar; the plugin adds its own bottom workbench (drag-to-split panes, per-session persistence) that coexists with the native bar
- **π Model-driven sidebar opens (opt-in)**: the `sidebar_open` tool lets the model actively open files / folders / web pages in the sidebar
- **π Service API**: `ctx.betterSidebar` is open to every plugin (`registerTab` / `registerFileViewer`); the built-in 5 tabs + 3 viewers go through the same API, and **28+ ecosystem plugins** already build on it (see "π Plugin Ecosystem")
- **β‘ On-demand loading**: ~325KB core at startup, editor / Mermaid / third-language dictionaries load on demand Β· **π i18n** follows DSH's language Β· **π Session isolation** persists layout per session
## π Installation
**Prerequisites**: DSH installed (`dsh web` boots), Node.js β₯ 20, pnpm β₯ 10.
**Supported DSH versions**:
> π **Channel and support line**: `v0.24.1` targets DSH **0.2.0-rc.1+** (0.2.0's first candidate rides npm's `next` dist-tag; `latest` is still 0.1.7-rc.2). **Pin the DSH version exactly**: `npm i -g @deepseek-ai/dsh@0.2.0-rc.1`. **Hosts on the 0.1.7 line should pin `dsh-apes-sidebar@0.22.1`**: 0.2.0 is a host minor bump, and caret ranges such as `^0.1.7-rc.1` fail the host's startup compatibility preflight on 0.2.0, which disables the whole profile row silently.
> π§ **Pick the plugin version that matches your DSH**:
>
> | Your DSH | Install command | Version / peer declared |
> | --- | --- | --- |
> | **0.2.0-rc.1+** (including a later 0.2.0 stable) | `dsh plugin --profile web add dsh-apes-sidebar@latest` | **0.24.1**, `^0.2.0-rc.1` |
> | **0.1.7-rc.1 β 0.1.7-rc.2** (and a later 0.1.7 stable; npm `latest` is still 0.1.7-rc.2) | `dsh plugin --profile web add dsh-apes-sidebar@0.22.1` | **0.22.1**, `^0.1.7-rc.1` |
> | 0.1.7-alpha.1 / 0.1.7-alpha.2 | **nothing to install** β move DSH to rc.1 first, then run the row above:
`npm i -g @deepseek-ai/dsh@0.1.7-rc.1` | β |
> | 0.1.6-alpha.2 and earlier, `0.1.5-rc.*` (including the 0.1.5-rc.3 that is npm's `latest`) | `dsh plugin --profile web add dsh-apes-sidebar@0.19.1` | **0.19.1**, `^0.1.5-rc.1` |
> | `0.1.5-alpha.2` | `dsh plugin --profile web add dsh-apes-sidebar@0.19.0-alpha.1` | `^0.1.5-alpha.2` |
> | `0.1.2-rc.*` | `dsh plugin --profile web add dsh-apes-sidebar@0.18.1` | `^0.1.2-rc.1` |
> | `0.1.2-alpha.2` | `dsh plugin --profile web add dsh-apes-sidebar@0.18.0-alpha.0` | `^0.1.2-alpha.2` |
> | `0.1.0-rc.8` / `0.1.1` | `dsh plugin --profile web add dsh-apes-sidebar@0.17.1` | `^0.1.0-rc.8` |
>
> Swap `web` for your own profile name. **Older versions are pinned exactly** (`@0.19.1`, not `@latest`), because `latest` moves forward with each new stable cut; conversely, do **not** install 0.19.1 on a 0.1.7 alpha β it would simply break.
```sh
dsh plugin --profile web add dsh-apes-sidebar@latest
```
> The plugin depends on no package that needs a build script (the terminal and `node-pty` went back to DSH wholesale), so installing is **one step**; once installed you can enable / disable it on DSH's own **Plugins page**.
Then **hard-refresh the browser** (Cmd/Ctrl+Shift+R) to see the sidebar (DSH hot-reloads client changes; only host-half updates need a restart).
**Or let DSH install it for you** β paste this prompt into any DSH session:
```text
Install the dsh-apes-sidebar plugin (a sidebar workbench for DSH):
1. Run: dsh plugin --profile web add dsh-apes-sidebar@latest (`latest` is the current stable)
2. When done, remind me to hard-refresh the browser (Cmd/Ctrl+Shift+R)
If anything fails, check the troubleshooting table in the README at https://github.com/omdsh-dev/DSH-better-sidebar
```
**Option 3: one-shot script** β from a clone of this repo, run `bash scripts/install.sh` (macOS / Linux / Windows Git Bash; native Windows uses `install.ps1`; `-h` for options) β it installs and registers the bundle in one go (including idempotent cleanup of an old manual mount row).
Updating
```sh
dsh plugin --profile web add dsh-apes-sidebar@latest
```
or bump the version in `~/.dsh/profiles/web/package.json` to the matching npm version (`"^0.22.1"`) and run `pnpm install`. Then hard-refresh the browser (Cmd/Ctrl+Shift+R) β client changes do not need a DSH restart.
Troubleshooting
| Symptom | Cause & fix |
|---|---|
| `Ignored build scripts` | pnpm 11 blocked a **transitive** dependency's build script. Run `pnpm approve-builds` (no `--all`) in the profile directory (`~/.dsh/profiles/web`) and follow its prompts β the plugin itself has no build-script dependency (`node-pty` left with the terminal). |
| `minimum release age` / version `< 24h` | The release is younger than 24 hours. Wait, or re-run once (pnpm auto-adds `minimumReleaseAgeExclude`). |
| "profile directory not found" | Run `dsh web` once so it initializes `~/.dsh/profiles/web`. |
| Two sidebars on the page | Double-mount. Old hand-written line: `~/.dsh/profiles/web/cordis.patch.yml` still has `- insert: ... better-sidebar ...` β delete it (a same-id duplicate mount makes the loader fail loudly with `duplicate loader entry id`). When an aggregate bundle (e.g. `@linxin666/dsh-web-ui-all`) mounts this package under a **different** id, the plugin's own bundle patch backs off automatically since 0.13.x (it detects an already-enabled mount of the same package name and does not mount itself) β no manual fix needed; if it still double-mounts, make sure the aggregate bundle precedes `dsh-apes-sidebar` in `dsh.profile.bundles`. |
| Where did my settings go after upgrading? | DSH 0.1.7 removed the registrable settings namespace: preferences now live on this plugin's **mount row** in the profile (entry id `better-sidebar` by default), not in `~/.dsh/settings.yaml`. On first boot the plugin imports the `dsh-apes-sidebar` section of the old `settings.yaml` (renamed `settings.yaml.imported` by the host) exactly once β only fields the current schema still declares, and only while that row has no user values yet, so it never overwrites values set after the upgrade. |
| Terminal unusable / shell fails to start | The terminal comes from **DSH's own `ui-sidebar-terminal`** (this plugin no longer ships a terminal or `node-pty`, and has no terminal settings). Consult DSH's own docs for problems; if the error mentions build scripts, see the row above. |
| `dsh: command not found` | Install DSH first, or run `npx -y --package @deepseek-ai/dsh dsh plugin --profile web add dsh-apes-sidebar@latest`. |
Install from source / develop (optional β alternative to the npm flow)
To debug local changes or track the dev branch, point the dependency at a local clone and build it yourself:
```text
1. git clone https://github.com/omdsh-dev/DSH-better-sidebar.git ~/Code/DSH-better-sidebar
cd ~/Code/DSH-better-sidebar && pnpm install && pnpm build
2. In ~/.dsh/profiles/web/package.json dependencies write "dsh-apes-sidebar": "link:"
3. Append this mount line to ~/.dsh/profiles/web/cordis.patch.yml (this row's `config` IS this plugin's settings form: the deployment limits `readLimit` / `mediaLimit` / `uploadLimit` / `listLimit` plus the user-preference fields β that is what the settings page writes; omit it and every field falls back to its schema default):
- insert:
- id: better-sidebar
name: 'dsh-apes-sidebar'
config:
readLimit: 524288
4. Run pnpm install in ~/.dsh/profiles/web
5. Restart DSH and hard-refresh
```
Update: `git pull && pnpm install && pnpm build` β just hard-refresh the browser (client changes hot-reload; only host-half changes need a DSH restart). To switch back to the npm channel, restore the matching npm version (`"^0.22.1"`) and re-run `pnpm install`.
Install via plugin-registry (optional β use either this or the main flow)
Prerequisite: DSH with [plugin-registry](https://github.com/dsh-external/plugin-registry) integrated (`dsh registry` available). **Enabling both channels double-mounts** (the Node half loads twice, the page gets two sidebars).
```sh
git clone https://github.com/omdsh-dev/DSH-better-sidebar.git && cd DSH-better-sidebar
pnpm install && pnpm build
node scripts/package-registry.mjs # assemble the registry/ staging (manifest + artifacts + README, not committed)
dsh registry install ./registry # install (disabled by default)
dsh registry enable dsh-external/dsh-apes-sidebar
```
Update: `git pull && pnpm install && pnpm build` β `node scripts/package-registry.mjs` β `dsh registry uninstall/install/enable`. Remove the other channel's mount before switching.
## πΌοΈ Feature Tour
> Below are real UI screenshots (two per row; click to zoom).
| | |
|---|---|
| **ποΈ File Workbench: Explorer**
Two explorer modes: embedded in the file preview / standalone file tree. Lazy-loading directory tree whose **expanded directories the host watches per directory and re-lists on change**, symlinks classified by target kind (directory links expand, dangling links flagged), global filename search, file/folder upload buttons plus drag-drop upload, context menu (open in new tab / open to the side / new folder / Open with β the hostβs probed OS handlers PLUS the pluginβs own targets (file manager / VS Code / Cursor / Zed / custom editors, SSH remotes, pin-to-menu) / copy paths / rename / delete), **Ctrl/Cmd multi-select with Shift range-select** (batch copy paths, batch delete, **zip and download**), **git changes colored by status with M/A/D/U letters**, and a hover `@file` button that references a file straight into the composer.

| **π Inline Preview: Markdown Β· HTML**
The Markdown preview renders **Mermaid diagrams** (strict-mode safe rendering + a second sanitize pass; click a diagram for a zoom modal with wheel-zoom and drag-pan), **README-level inline HTML** (badge walls ``, `` blocks nesting markdown, inline tags in table cells β DOMPurify-sanitized, `