# DSH Sidebar Connect your vault to **[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)** (DSH) and run its agents from a sidebar panel inside Obsidian. `Español:` [README.es.md](./README.es.md) ## What it does - Adds a **sidebar panel** that embeds the DeepSeek Harness web UI in an iframe, so you can run your agents without leaving the vault. - **Manages the local server for you**: it starts `dsh web` on a free loopback port, reads the launch URL, and loads it in the panel. Stop it or restart it from the toolbar. - **Never blocks on a busy port**: it probes the configured port first and automatically picks the next free one. - **Ships a token-saving knowledge graph bridge** (optional): it installs the bundled `dsh-graphify` package into your DSH profile, which gives agents the tools `graphify_search` and `graphify_stats` over a local graph of pre-extracted concepts. Agents then answer from that graph instead of re-reading raw notes, which costs fewer tokens. - **Bilingual UI**: English, or Spanish when Obsidian runs in Spanish. ## Requirements - **Obsidian desktop** 1.4.0 or newer (Windows, macOS or Linux). The panel is desktop-only because it starts a local process. - **DeepSeek Harness installed** so that the `dsh` command is available on your `PATH`: ```bash npm i -g @deepseek-ai/dsh ``` If `dsh` lives somewhere unusual, set an absolute path to its `bin.js` in the plugin settings. - Model credentials configured in DSH (for example through the DSH web UI, or the `DEEPSEEK_API_KEY` environment variable). ## Installation ### From the Obsidian community directory 1. Open **Settings → Community plugins → Browse**. 2. Search for **DSH Sidebar** and select **Install**, then **Enable**. ### Manually (or while the plugin is not listed yet) 1. Create the folder `/.obsidian/plugins/dsh-sidebar/`. 2. Copy `main.js`, `manifest.json` and `styles.css` into it. 3. Reload Obsidian and enable **DSH Sidebar** in **Settings → Community plugins → Installed plugins**. ### While developing (hot reload) Use [BRAT](https://github.com/TfTHacker/obsidian42-brat) and add this repository, or copy the three files above into your vault after every change. ## Usage 1. Click the **bot icon** in the left ribbon, or run the command **DSH Sidebar: Open panel**. 2. Press **Start**. The panel waits for the server's ready line and then loads the DSH UI. 3. Work with your agents inside the panel. Use **Reload** if the page looks stale, **Browser** to open the same URL in your default browser, and **Logs** to inspect the server output. ## Settings | Setting | Default | Description | | --- | --- | --- | | dsh CLI path | *(empty)* | Empty uses `dsh` from `PATH`. Otherwise an absolute path to a DSH `bin.js`. | | Port | `3081` | Port for the web server. `0` lets the OS pick. Use a different port than another running DSH instance (for example the VS Code extension on `3080`). | | Auto-start | on | Start the server when the panel opens. | | Embed mode | `direct` | `direct` loads the launch URL (which carries the token). `proxy` runs a local proxy that re-mints and injects the session cookie, as a fallback for setups where the iframe cannot carry the cookie. | | Extra args | *(empty)* | Extra CLI arguments, one per line, for example `--trusted-host`. | | Knowledge graph bridge (graphify) | off | Install the bundled `dsh-graphify` package into your DSH profile so agents can search a local knowledge graph. | | DSH profile | `web` | The profile started by `dsh web`. | | Knowledge graph folder | *(empty)* | Folder holding `.graphify_chunk_*.json` files. Empty uses `/graphify-out`. | | Install / repair bridge · Remove bridge | — | Manual buttons; the current state is shown below them. | ## The knowledge graph bridge The bridge is the part of this plugin that is not a plain iframe wrapper. 1. Build a graph of your vault once — the plugin expects `.graphify_chunk_*.json` files (a `nodes` array of extracted concepts) in `/graphify-out`, or in the folder you configure. 2. In the plugin settings, turn on **Knowledge graph bridge (graphify)** and press **Install / repair bridge**. 3. Press **Start** (or restart the server). Agents now have two extra tools: - `graphify_search(query, limit?)` — returns matching concept labels, their type, source file and a short rationale. - `graphify_stats()` — node count and source files, so the agent knows what the graph covers. The installer copies the bundled package to `$DSH_HOME/profiles//packages/dsh-graphify/` and appends one loader entry to that profile's `cordis.patch.yml`, marked with a comment. It is idempotent: if you already registered graphify by hand it leaves your entry alone, and it refuses to touch a `cordis.patch.yml` that is not a top-level array. A backup (`cordis.patch.yml.dsh-sidebar-bak`) is written before any change, and **Remove bridge** undoes only what the plugin added. ## How authentication works DSH 0.1.2 and later authenticate browsers with a `SameSite=Strict` cookie that is minted by a `GET /?token=…` 303 exchange. The plugin starts its **own** `dsh web` process, reads the ready line (`dsh web: http://127.0.0.1:/?token=…`) from that process, and loads that URL in the iframe so the cookie is minted inside the frame. Because the plugin owns the process, it always has the token; an already-running server started elsewhere cannot be embedded this way, which is why the plugin prefers to start its own instance on a free port. ## Troubleshooting | Symptom | Cause | Fix | | --- | --- | --- | | `listen EADDRINUSE` in the log | Another process already holds the port. | The plugin already retries on the next free port. If it still fails, change **Port** in the settings. | | `dsh is not recognized` / spawn error | `dsh` is not on the `PATH` that Obsidian sees. | Set an absolute path to the DSH `bin.js` in **dsh CLI path**. | | Log shows a DSH plugin-tree error | A DSH profile plugin failed to load. | Read the log: the failing plugin is named. Fix or remove that entry in `$DSH_HOME/profiles//cordis.patch.yml`. | | Panel stays blank | The iframe could not authenticate. | Switch **Embed mode** to `proxy` and press **Start** again. | | Server floods the log while starting | Normal DSH boot output. | Press **Logs** to hide it. | ## Privacy and data use - **Localhost only.** The plugin talks to DSH exclusively over `127.0.0.1`. It makes no outbound requests, contains no telemetry, and does not download anything. - **It starts a local process.** The plugin spawns `dsh web`, which runs with your user's permissions and reads the DSH data directory (`~/.dsh`). DSH itself may read files outside your vault, and — when you ask it to run a task — may make outbound requests to the model provider you configured. That behaviour belongs to DSH, not to this plugin. - **It writes outside your vault, but only if you ask it to.** The knowledge graph bridge copies a package into `$DSH_HOME/profiles//packages/` and edits that profile's `cordis.patch.yml`. Both live outside the vault by design, because that is where DSH loads its plugins from. A backup is written first, the edit is idempotent, and the plugin refuses to modify a file it does not understand. - **It reads your DSH settings indirectly** because the spawned server loads them. The plugin itself stores only the settings shown above in `data.json`. - **No credentials are collected.** The plugin never reads or transmits your API keys; DSH keeps them in its own credential store. - **No self-updating.** The plugin never installs or updates itself or its dependencies; updates arrive through Obsidian. ## Credits - [Claudian](https://github.com/YishenTu/claudian) — the Obsidian plugin that inspired embedding an AI agent in a sidebar panel. - [deepseek-harness-vscode](https://github.com/zwb8926/deepseek-harness-vscode) — the VS Code extension whose spawn/ready-line and cookie-proxy approach this plugin follows. - The DeepSeek Harness and Obsidian teams. ## License [MIT](./LICENSE)