# DSH Dock [![Obsidian 插件市场 已提交](https://img.shields.io/badge/Obsidian%20%E6%8F%92%E4%BB%B6%E5%B8%82%E5%9C%BA-%E5%B7%B2%E6%8F%90%E4%BA%A4-7C3AED?style=flat-square)](https://obsidian.md/plugins?id=dsh-dock) [![GitHub release](https://img.shields.io/github/v/release/Elervi/obsidian-dsh-dock?style=flat-square)](https://github.com/Elervi/obsidian-dsh-dock/releases) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow?style=flat-square)](LICENSE) > 把官方 **DeepSeek Harness Web**(127.0.0.1:3080)停靠进 Obsidian 侧边栏——跑官方 `dsh CLI`、官方 UI 原样嵌入,轻量高效。 [![🇨🇳 中文](https://img.shields.io/badge/%E4%B8%AD%E6%96%87-%E5%BD%93%E5%89%8D%E9%A1%B5-7C3AED?style=flat-square)](#) [![🇬🇧 English](https://img.shields.io/badge/English-%E8%8B%B1%E6%96%87%E7%89%88-0969DA?style=flat-square)](README.en.md) ## ✨ 特性 - 📦 **开箱即用** — Obsidian 市场一键安装,或复制 3 个文件 - 🪟 **官方原生** — 定位 dsh → 拉起官方 `dsh web` → iframe 原样嵌入 - 🔐 **鉴权自动接管(B2)** — 官方 dsh web 的浏览器鉴权 cookie 是 `SameSite=Strict`,跨站 iframe 无法认证。本插件在面板内核起一个本机反向代理,读取 dsh web 凭证库的会话签名密钥、注入 cookie 并重写 Host/Origin 通过官方 `/api` 信任围栏 —— 面板无需 launch token,无论服务是新起还是已存在都能直接显示(HTTP + WebSocket 双向代理) - 🗂️ **Per-vault 隔离** — 会话按库独立、配置全局共享,多库并行互不串扰 - 🔌 **Obsidian API 桥(B1)** — 插件加载即在本机 127.0.0.1 起一个 token 鉴权的 HTTP 桥,把 `app.vault` / `metadataCache` / `fileManager` 的官方解析结果喂给 DSH 侧 `vault_*` 工具(桥优先、文件回退),工具写后 Obsidian UI 与索引即时刷新 - 🤝 **珠联璧合** — 与 [dsh-tool-obsidian-vault](https://github.com/Elervi/dsh-tool-obsidian-vault) 联动,Obsidian 内直接驱动 Agent 笔记工作流 - 🧹 **进程自清洁** — 卸载/停用 SIGTERM 关停;崩溃残留的孤儿进程下次启动自动清扫 ## 📦 安装 > 前置:Obsidian **桌面端** ≥ 1.5.0 · `npm i -g @deepseek-ai/dsh` · Node ≥ 20 **① 插件市场(推荐)**:设置 → 第三方插件 → 浏览 → 搜索 **DSH Dock** → 安装并启用。 **② 手动安装**:把 `main.js` + `manifest.json` + `styles.css` 复制到 vault 的 `.obsidian/plugins/dsh-dock/`,再在设置中启用。 启用后点侧边栏机器人图标(或命令「打开 DSH 面板」)。首次启动自动初始化 `$DSH_HOME` 并拉起官方 `dsh web`,几秒后面板出现。 ## 🗂️ Per-vault 隔离(默认) **会话隔离、配置共享**——模型、密钥、主题配一次全库生效,只有会话/历史按库独立。 | 维度 | 行为 | | --- | --- | | 会话 / 历史 | 每库独占 `~/.dsh/vaults/<库名>-` | | 监听端口 | `port + vaultRoot hash % 4096`(冲突概率 ~1/4096) | | vault 识别 | 注入 `DSH_OBSIDIAN_VAULT_PATH` + 标记文件跟随(不覆盖 cwd) | | 模型 / 密钥 / 主题 / presets | 全局共享:软链 `profiles/` + `cordis.patch.yml` 指回 `~/.dsh` | ## ⚙️ 设置 | 设置 | 默认 | | --- | --- | | dsh CLI 路径 | 自动探测(`$DSH_BIN` → npm 全局) | | Node 可执行文件 | 系统 node(最稳定) | | 监听端口 | 3080(≥1,不用 0 表示「OS 分配」——launcher 无需发现子进程实际端口) | | DSH_HOME 模式 | per-vault 隔离(可切换 shared / 自定义) | | 随 Obsidian 自动启动 | ✅ 开 | | Obsidian API 桥 | ✅ 开(127.0.0.1 回环,token 鉴权,端口 18080+ 独立于 dsh web) | ## 🔧 **Obsidian API 桥(B1)** ``` node /lib/bin.js web --host 127.0.0.1 --port env: DSH_HOME → 等待就绪(秒退立即报错,不盲等)→ iframe 面板 → http://127.0.0.1:/ 端口上已有 DSH 服务 → 直接挂接,不重复拉起 Obsidian API 桥(B1,独立于 dsh web): createBridgeServer(service=ObsidianBridgeService(app)) @ 127.0.0.1:<18080+hash> → /health /v1/{current,notes,note,metadata,frontmatter,backlinks,search,tags,folders} → POST /v1/{write,edit,frontmatter,rename}(Bearer token 鉴权,仅回环) → 桥地址/token 经 DSH_OBSIDIAN_BRIDGE_URL/TOKEN env + current-vault.json 标记文件 双通道注入 DSH 进程;工具侧「桥优先、文件回退」 ``` ## ⚠️ 已知限制 - 仅桌面端(依赖 `child_process`) - 端口被**非 DSH 服务**占用 → 秒退报错;被另一 DSH 占用 → 直接挂接 - 会话全文搜索需 Node ≥ 22.5 - **dsh web 鉴权依赖 `~/.dsh/.credentials.yaml`**:面板代理需要读取其中的 `client-connection/browser-session` 签名密钥来注入 cookie。若目标 dsh web 用了非默认/非共享的凭证库路径,面板将报「面板鉴权代理启动失败」(届时用「在系统浏览器中打开」访问官方地址)。 - 桥的 `vault_rename_note` 遵循 Obsidian「自动更新内部链接」设置(关闭时不改写引用,与 Obsidian UI 行为一致) - 桥覆盖 vault / fileManager / metadataCache / workspace 中与笔记工作流相关的全部核心 API;全文搜索无公开 API(桥内实现 substring/regex),附件二进制读写与 `/v1/events` 变更推送未做 ## 🤝 珠联璧合 [dsh-tool-obsidian-vault](https://github.com/Elervi/dsh-tool-obsidian-vault) 是 **DSH 侧**工具插件(20 个 `vault_*` 工具,让 Agent 直接读写本地 Obsidian 笔记);本插件是 **Obsidian 侧**外壳——一个管「门」(让 DSH 住进 Obsidian),一个管「钥匙」(让 Agent 认识 Obsidian)。 | 环节 | 本插件(Obsidian 侧) | 工具侧如何受益(DSH 侧) | | --- | --- | --- | | 启动 DSH | 点机器人图标,面板即官方 DSH Web UI | 无需自己开终端跑 `dsh web` | | 定位当前库 | 注入 `DSH_OBSIDIAN_VAULT_PATH` / `DSH_OBSIDIAN_VAULT_NAME` | 「注入的本库」优先于工作目录巧合,多库同开不串 | | 会话工作目录 | 不覆盖(保持 dsh 默认);库识别走注入的 env + 标记文件 | cwd 与库根是两个独立概念,不合并 | | 多库并行 | 端口按库 hash 偏移互不冲突 | 面板共享同一份 preset,一次装好全库可用 | | 配置共享 | `cordis.patch.yml` 指回 `~/.dsh` | 配一次全库生效,只有会话/历史按库隔离 | **三步启用**:① 装好本插件 → ② 在 DSH 侧装 **Obsidian 模式** preset(复制其 `preset/` 到 `~/.dsh/.agent-presets/obsidian`)→ ③ 面板新建会话选「Obsidian 模式」,说「读一下今天的笔记」「把这段整理进 [[xxx]]」,Agent 自动读写当前库,无需任何路径配置。 > 仅 **per-vault** 模式(默认)注入 env(库名/路径 + 桥地址/token);**shared** 模式多库共用一个服务,工具侧退回「最近活跃打开库 / 工作目录」解析。cwd 一律不覆盖——库识别靠 `DSH_OBSIDIAN_VAULT_PATH` 与标记文件。 ## License MIT