wozoulesky/dsh-obsidian

dsh-obsidian

DSH(DeepSeek Harness)嵌入 Obsidian 的 AI 协作者插件:聊天侧边栏、内联编辑、@提及与计划模式(连接本地 http://127.0.0.1:3080)

Uncategorizedagentai-assistantdeepseek

DSH Bridge

Embed your locally running DeepSeek Harness (DSH) into Obsidian as an AI collaborator: your vault becomes its working directory, and DSH can read, write, and search your notes directly.

中文文档

Why this plugin

Most Obsidian ↔ agent bridges wrap a web UI or shell out to a CLI. This one is a native client: it speaks DSH's own RPC and event stream, then renders everything with Obsidian's own UI.

  • Native, not embedded — chat, tool cards, approvals and plan mode are real Obsidian UI: your theme, your fonts, your hotkeys.
  • Inline edit with a word-level diff — select text, give an instruction, review the diff, apply; Cmd+Z undoes it.
  • Approvals land where you are — DSH's write/exec confirmations and its questions appear inside the panel, no window switching, and they survive a reconnect.
  • Connection diagnosis — 401 / 404 / connection-refused are translated into an actionable conclusion (Settings → Diagnose connection).
  • Engineered to last — 550+ unit tests, strict TypeScript build, byte-reproducible artifacts, listed in the community directory.

The plugin is a client, not a runtime: it needs a local DSH to talk to (see Prerequisites). If something looks wrong, the diagnose button will tell you which of the two it is.

Prerequisites

  • A running DSH instance on your machine. Don't worry about the port: since DSH 0.2.1 the desktop app is assigned a random port on each launch (it used to pin 19387), and the dsh web command defaults to 3080. The plugin auto-discovers the real port on startup — it tries the static candidates first, then reverse-resolves the Cookie store that the DSH desktop app writes, to locate the random port — and saves it back to settings — you normally don't need to type an address. It also re-discovers while running: restart DSH without touching Obsidian and the plugin notices the connection repeatedly failing, finds the new port, and switches over on its own (typically ~4s) — no reload needed
  • Your vault must be inside DSH's accessible directory scope (decided by DSH's sandbox / workspace config)
  • Obsidian ≥ 1.7.2, desktop build only. These are two different constraints:
    • 1.7.2 is an Obsidian version requirement (sidebar revealLeaf and related APIs). Upgrade Obsidian if you are below it.
    • "Desktop build" is an Obsidian client-form requirement, unrelated to the version: the plugin signs its auth cookie with the secret in ~/.dsh/.credentials.yaml, and mobile has no Node filesystem access, so it cannot sign one. Hence isDesktopOnly: true.
    • This does not constrain how you run DSH: auth uses the same client-connection/browser-session secret in ~/.dsh/.credentials.yaml, regardless of whether DSH runs as the desktop app or via dsh web; 3080 (the dsh web default) is already a built-in static candidate. The desktop app is fully verified on real hardware; dsh web follows the same auth and protocol path but has not been separately end-to-end tested (see the compatibility table below).

Features

Conversation

  • Chat sidebar — streamed responses, tool-call cards, session switching and creation, "load older" pagination, and automatic re-sync after reconnects
  • Approval & question popups — retryable, grouped per session, replayed after a reconnect
  • Thinking process — collapsible reasoning block above each reply, streamed live and folded once the turn completes
  • Image attachments — attach images from your vault to a prompt; the agent reads them directly

Editing your notes

  • Inline edit — select text + hotkey → instruction → word-level diff preview → apply (editor selection is re-validated before applying; large selections degrade to a plain confirm dialog)
  • @mentions — type @ to pick vault files (@file:path, content injected) or folders (@folder:path, directory tree injected), with truncation and missing-file notices
  • Slash commands & plan mode — commands come from the running DSH (so the list always matches your install), plus the local /clear; Shift+Tab toggles plan mode with a status banner

Context & control

  • Model & reasoning effort — pick provider/model and reasoning effort from the panel; the list is grouped from your DSH model catalog
  • Context usage — a status line showing projected tokens against the context window, plus output tokens
  • Todo list — the agent's live todo list with pending / in-progress / completed states
  • Goal panel — view and control a long-running goal (create / pause / resume / complete / clear)

Long sessions stay bounded: when DSH compacts history, replaced messages collapse into the summary instead of piling up.

Screenshots

Chat sidebar@ Mention picker
Chat sidebar with streamed conversation@ mention file picker
Inline edit diff previewApproval popup
Inline edit word-level diff previewDSH tool approval popup
Thinking process & context usageTodos & goal
Collapsible reasoning block while streaming, with the context/usage status lineLive todo list with three states and the goal bar
Model & reasoning effortConnection diagnosis
Model dropdown grouped by provider, next to the reasoning-effort selectorSettings → Diagnose connection reporting a healthy connection

Installation (Community Plugins)

  1. Settings → Third-party plugins → Browse → search DSH Bridge → Install → Enable (desktop only)
  2. Just make sure DSH is running — no address to fill in: the plugin auto-discovers the real port and saves it back to settings. If DSH starts later — or restarts on a new port — the plugin re-discovers and reconnects by itself; click Diagnose in the plugin settings only if it still can't connect

The UI language follows your Obsidian language setting automatically (Chinese in Chinese locales, English elsewhere) — no manual switching.

Prefer a manual install? Grab the latest artifacts from the GitHub releases page and extract them into vault/.obsidian/plugins/dsh-bridge/.

Installation (local / dev)

  1. npm install && npm run build
  2. Copy main.js, manifest.json, and styles.css into vault/.obsidian/plugins/dsh-bridge/
  3. Settings → Community plugins → enable "DSH Bridge"

Privacy

All data flows through your local DSH to its configured model providers, using the same policy as the DSH Web GUI. The plugin sends no telemetry.

Translations / Localization

The plugin ships with all UI strings in a key-value table (built-in default: Chinese). To switch the UI to another language:

  1. In the plugin settings tab, click Export i18n template — this creates dsh-bridge.i18n.json at the root of your vault (visible in Obsidian's file explorer).
  2. Replace the values with your translations (or hand the file to your local DSH / any translator).
  3. Reload Obsidian (or disable/enable the plugin) to apply — repeatable.

The vault-root file takes priority; a legacy i18n.json inside the plugin directory (.obsidian/plugins/dsh-bridge/) is still read as a fallback. Missing keys or invalid JSON silently fall back to the built-in defaults. In v0.1.x, model-facing instructions (inline-edit prompt, @mention expansion) intentionally remain in Chinese; the UI-only string table is safe to translate.

Development

npm install
npm run dev    # watch build
npm test       # unit tests

Architecture

Transport: unary RPC over Node http (POST /api/<namespace>/<method> with {args} payload + self-signed browser-session cookie); live streams over a bundled ws WebSocket (/api/remote.mux — session/follow, session/control, $events). A core layer folds session events into view models; a UI layer renders the sidebar and modals.

DSH compatibility

DSH version linePlugin versionStatus
0.2 line (verified on 0.2.0-rc.2)0.1.8+ (current)✅ Protocol-layer verification and in-Obsidian UI acceptance both pass (2026-10-01): the plugin's own code connected to a live 0.2.0-rc.2 over real HTTP + WebSocket — authentication, all 18 RPC endpoints, and the $events / session/control / session/follow streams pass; and a real Obsidian 1.13.7 accepted @-mentions, streaming output, approval-gated file writes, inline-edit diff, and port auto-detection. 0.2 did not change auth, the RPC envelope, or the WS frame protocol, so no upgrade work is needed. The one gotcha is the port: the desktop app used to pin 19387 but since 0.2.1 it is assigned a random port on each launch (dsh web still defaults to 3080) — the plugin auto-discovers it (static candidates first, then reverse-resolving the desktop app's Cookie store), so you normally don't set it by hand. Per-item record and verification boundaries: docs/dsh-0.2-compat-audit-2026-10-01.md (see its expiry note for the port claim)
0.1.5 line (verified on 0.1.5-rc.1)0.1.6+ (incl. 0.1.7)✅ Verified end to end on a real vault (2026-09-13): streamed output, approvals, inline-edit diff, reconnect
dsh web launch mode (defaults to port 3080)0.2.0+⚠️ not separately end-to-end tested. Auth, RPC envelope, and WS frame protocol are identical to the desktop app (same client-connection/browser-session secret in ~/.dsh/.credentials.yaml), and 3080 is already the first built-in static candidate, so it is expected to work; but as of 0.2.0 it has not been run through full acceptance on a real dsh web instance. Please open an issue if you hit problems.
0.1.2 line (0.1.2-rc.1, 0.1.2)0.1.5+✅ Supported — the contract this plugin was built against. 0.1.6+ keeps it working through capability probing: the 0.1.5 streaming channel is requested field by field and dropped automatically if the server rejects it. Verified on a real machine at plugin 0.1.5, covered by unit tests since
before 0.1.2 (e.g. 0.1.0-rc.6)≤ 0.1.4❌ Not supported — returns 401/404. Upgrade DSH, or stay on plugin 0.1.4
newer than 0.2 (0.3+)latest plugin⚠️ Unverified — DSH ships often and has already changed this plugin's contract twice (0.1.2 → 0.1.5). If the panel breaks after a DSH upgrade, check for a plugin update first

Direct filesystem access (disclosed for community review): DSH's browser-session authentication requires reading the signing secret from ~/.dsh/.credentials.yaml (the DSH process's credentials store, outside the vault). The plugin reads this file read-only — it never writes, never logs its contents, and only uses the secret to sign the per-request cookie required by DSH's browser-session API (0.1.2-rc.1 onwards). The vault API cannot reach this path (it is outside the vault root), so Node fs is required for this one purpose.

  • obsidian-project-management — the Obsidian-based project management skill that governs this plugin's development workflow (project records are tracked in a local Obsidian vault).