DeepSeek Harness Hub
← 返回列表

SilenZerOrz/obsidian-dsh-acp

DeepSeek 客户端兼容 / 相关生态spec-screened在 GitHub 查看 ↗
✓ 可直接安装

obsidian-dsh-acp 是一个将 DeepSeek HarnessDSH 接入 Obsidian 的

自动检查通过:npm 包已发布且 engines 声明满足基线(声明 Node >=22.13);该结论来自程序自动检查,未经人工实机验证。 · 最近上游提交 2026/9/18 · 已提供中文文档
综合分
30.8
GitHub 分
30.8
用户评分
★ Stars
1
周下载量
兼容 / 相关生态插件(非 dsh 原生,请按其对应运行时安装)
git clone https://github.com/SilenZerOrz/obsidian-dsh-acp.git
数据截至 2026/9/18(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
安装兼容性检查✓ 自动检查通过

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

npm 包obsidian-dsh-acp @ 0.2.3
Node 引擎要求 >=22.13 · 基线 Node 22.19 满足
dsh CLI 依赖未声明 dsh 版本约束
入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后验证 2026/9/19 09:09:04

依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery@deepseek-ai/cordis
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

obsidian-dsh-acp

obsidian-dsh-acp 是一个将 DeepSeek Harness(DSH) 接入 Obsidian 的
ACP(Agent Client Protocol) 插件/适配器:把它配置为 Obsidian Agent
Client 插件中的一个 Custom Agent(或作为 cordis 插件装进 DSH profile),
就能在 Obsidian 界面里直接通过 ACP 驱动 DSH,用 DeepSeek Harness 完成对话与
任务,而不需要切出 Obsidian。

这是一个 ACP 服务器(通过 stdin/stdout 讲 ACP v1 协议),作用是桥接:

Obsidian (Agent Client 插件)
│  ① 作为 Custom Agent 通过 ACP 拉起
▼
obsidian-dsh-acp (ACP server)
│  ② 每次 prompt 拉一个
▼
dsh --profile headless ""   (DeepSeek Harness 一次性任务)

它镜像了 claude-agent-acp 包装 Claude Code 的方式。每轮 prompt 会:拉一次
dsh --profile headless ""(一次性任务),把 DSH 输出流式回传为
agent_message_chunk 更新,结束时返回 end_turn 结果。

支持会话管理:持久化的会话列表(Obsidian "Session history" 可 reload)、
session/fork 会话分支、以及把每轮对话写回 DSH 归档。

本仓库包含两个互补的部分:

1. dsh-acp.mjs —— 独立的 ACP 服务器二进制(bin: dsh-acp)。
GUI ACP 客户端(Obsidian Agent Client)会直接将其作为子进程启动。
2. index.mjs —— 一个 [cordis][cordis] 插件,注册 dsh.acp 服务,并在 harness
内部 管理适配器进程,可通过
dsh plugin --profile  add obsidian-dsh-acp 使用。

工作原理

Obsidian Agent Client ──(基于 stdin/stdout 的 ACP JSON-RPC)──▶ dsh-acp ──spawn──▶ dsh --profile headless ""
▲  session/update 分块                        │
└──────────────── stdout 流式返回 ─────────────┘

- 通过进程的 stdin/stdout 使用 ACP v1(换行分隔的 JSON-RPC)。
- 将 DSH 输出以 agent_message_chunk 更新流式返回,然后返回一个 result
(stopReason: "end_turn")。
- 会话无状态(每一回合相互独立);cwd 会被保持。

双 runtime 架构(v0.2.2+ / P2 长驻改造骨架)

为了在 Obsidian 端实现工具审批弹窗和思考/执行过程实时显示,adapter
需要从「每轮 spawn headless 子进程」切换到「双 runtime 分发」:

┌─────────────────────────────────────────────────────────────────┐
│  入口 A:dsh-acp.mjs 独立二进制(Obsidian Agent Client 拉起)       │
│  · 无 cordis ctx,runtime.mode 永远 = "spawn"(向后兼容)          │
│  · 走 v0.2.1 现有路径:spawn dsh --profile headless               │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│  入口 B:index.mjs cordis 插件(dsh web 加载)                     │
│  · 与 dsh 同进程,runtime.mode 默认 = "long"                       │
│  · long 模式:in-process import lib/long-runtime.mjs              │
│  · 订阅 ctx.llm.stream() chunks → ACP sessionUpdate               │
│  · headless profile 自动降级 spawn(保护现有 headless 用户)       │
└─────────────────────────────────────────────────────────────────┘

当前状态(v0.2.2 / P1.0 骨架):long 模式已可被 cordis 插件在
in-process 启动,但接入点先 throw P1.0 placeholder,等待 P1.5 接入
ctx.llm.stream()、P2.0 接入 4-mode 审批、P2.5 接入 temperature / reasoningEffort。
spawn 路径 100% 不变。

模式解析优先级(lib/runtime-switch.mjs::resolveRuntimeMode()):

1. DSH_PROFILE=headless → 强制 spawn(headless 用户不变)
2. DSH_ACP_RUNTIME_MODE=long|spawn 显式覆盖
3. DSH_IN_CORDIS=1 → long(cordis 插件 in-process 标记)
4. 默认 spawn(standalone binary 向后兼容)

配置示例:

强制 long 模式(cordis 插件内)
DSH_ACP_RUNTIME_MODE=long node dsh-acp.mjs

long 初始化失败时回退 spawn(默认开启)
DSH_ACP_SPAWN_FALLBACK=true DSH_ACP_RUNTIME_MODE=long node dsh-acp.mjs

4 种 permission 模式(默认 "default",最安全)
DSH_ACP_PERMISSION_MODE=acceptEdits    # 或 dontAsk / bypassPermissions
DSH_ACP_PERMISSION_TIMEOUT_MS=300000   # 5min 超时默认 reject
DSH_ACP_PERMISSION_EDIT_TOOLS="Edit,Write,MultiEdit,NotebookEdit"

会话功能

在"无状态单回合"模型之上,dsh-acp 增加了一个持久会话层
(archive-store.mjs),提供三件事:

1. 重新加载会话列表 —— session/list 从磁盘上的 JSON 索引(默认
~/.dsh-acp/dsh-acp-sessions.json)返回持久会话,因此 Obsidian 的
"Session history" 重新加载时,即使适配器重启也能看到真实会话。初始化时
适配器会声明 sessionCapabilities.list。
2. 会话分支(fork) —— session/fork 把源会话的消息历史深拷贝到一个新的
会话 id,记录父级链接,并声明 sessionCapabilities.fork,从而让客户端的
"fork" 操作生效。
3. 备份每一回合 —— 每个完成的回合(用户 + 助手)都会追加写入到 DSH 格式的
事件归档:
/dsh-acp-archives//session-/session.jsonl。
它存放在 dsh-acp-archives/(而不是 web 进程的 sessions/)下,以免普通
.jsonl 与主进程 zstd 压缩的会话日志冲突。如需改为放进 sessions/,可设置
DSH_ACP_ARCHIVE_IN_MAIN=1(仅当你以相同压缩模式运行归档时)。

4. 永久删除会话(v0.1.4) —— session/delete 删除会话记录并同时清理磁盘归档目录(/dsh-acp-archives/ 与 /sessions/ 双 root,目录名按记录的 session- 键),因此删除后不会在下次 list"复现"。适配器声明 sessionCapabilities.delete。

session/resume 和 session/load 可重新打开已保存的会话。

持久化与并发(v0.1.4):内存索引按短防抖(DSH_ACP_PERSIST_DEBOUNCE_MS)落盘并在退出前 flush,突发消息合并为少量磁盘写;多个适配器进程共享同一 store 时,写前先合并磁盘副本、且绝不复活已删除记录。完整 REQ 变更见 docs/计划/开发现状.md。

环境要求

- Node.js >= 22.13
- 可正常启动的 dsh 后端(参见 Headless profile 引导)

文件

| 路径 | 作用 |
|------|------|
| dsh-acp.mjs | 独立的 ACP 服务器二进制(bin: dsh-acp,双 runtime 分发入口) |
| archive-store.mjs | 持久会话存储 + DSH 归档写入器 |
| index.mjs | cordis 插件入口(dsh.acp 服务 + 适配器进程管理器;long 模式 in-process host) |
| lib/runtime-switch.mjs | 双 runtime mode 解析 + 4-mode permission config + tryLongFallbackSpawn |
| lib/long-runtime.mjs | long 模式 LongRuntime class(v0.2.2 占位;P1.5+ 接入 ctx.llm.stream) |
| lib/client.js | dsh web React 面板(0.2.1 默认隐藏 npm files,仅 test 分支打包) |
| cordis.patch.yml | 供 dsh plugin ... add obsidian-dsh-acp 使用的插件插入层 |
| scripts/dsh-acp.js | ACP 服务器适配器(运行时参考副本) |
| scripts/test-client.js | 用于独立验证的 ACP 客户端测试工具 |
| acp-feature-test.mjs | 协议层功能测试(list / fork / resume / archive;--runtime long|spawn) |
| install.sh | 一键安装脚本(DSH profile + Obsidian custom agent) |

一键安装

包内附带 install.sh —— 一个参数化安装脚本,可以 (a) 通过官方 dsh plugin add
把插件装进 DSH profile,(b) 给 Obsidian Agent Client 配置自定义代理,并可选配置
环境变量。它幂等、改任何文件前都会备份、支持任意 Obsidian vault,并可用
--dry-run 预演。

先预演(推荐,不改任何东西)
./install.sh --obsidian-vault /任意/vault/路径 --dry-run

正式安装进 "web" profile + 配置 Obsidian
./install.sh --obsidian-vault /任意/vault/路径

装进其它 DSH profile
./install.sh --profile headless --obsidian-vault /任意/vault/路径

只装 DSH,跳过 Obsidian
./install.sh --no-obsidian

运行 ./install.sh --help 查看全部选项。要点:

| 选项 | 含义 |
|------|------|
| --profile  | 安装到的 DSH profile(默认 web) |
| --dsh-home  | DSH 数据根(默认 $DSH_HOME 或 ~/.dsh) |
| --obsidian-vault  | 任意要配置的 Obsidian vault(支持任意路径) |
| --package  | 插件来源: /  / link: |
| --node-bin  | 自定义代理使用的 node 二进制 |
| --profile-env | 打印推荐的适配器环境变量 |
| --no-obsidian | 跳过 Obsidian 配置步骤 |
| --dry-run | 只预演,不做任何改动 |
| --uninstall | 恢复备份 + 卸载 DSH profile 插件(dsh plugin remove)+ 移除 Obsidian 本脚本添加的配置 |

独立使用

安装包之后(或直接从检出目录运行):

node dsh-acp.mjs            # 在 stdin/stdout 上提供 ACP v1 服务
node scripts/test-client.js "reply with just the word HELLO"

配置(Obsidian Agent Client)

配置自定义代理有两种方式:一键安装(运行 install.sh --obsidian-vault ,
见上文)或如下手动配置。

Obsidian 内手动操作步骤:

1. 安装 Agent Client 社区插件(设置 → 第三方插件 → 浏览 → 搜索 "Agent Client")
并启用。
2. 打开插件设置 → Custom Agents → Add。
3. 填写:
- ID:dsh-acp
- Display name:DeepSeek Harness (ACP)
- Command:本包 dsh-acp.mjs 的绝对路径
- Args:(空)
- Env(可选):如 DSH_ACP_LOG_DIR → /绝对/路径/到/logs
4. 将插件的 nodePath 设为真实的 node 二进制(>= 22.13),以便 shebang 解析。
5. 重载 Obsidian(Cmd-R),在代理选择器中选中 DeepSeek Harness (ACP)。

如果直接编辑 data.json:

{
"id": "dsh-acp",
"displayName": "DeepSeek Harness (ACP)",
"command": "/absolute/path/to/dsh-acp/dsh-acp.mjs",
"args": [],
"env": [{ "name": "DSH_ACP_LOG_DIR", "value": "/absolute/path/to/dsh-acp/logs" }]
}

cordis 插件用法

通过官方插件机制安装进某个 DSH profile(package.json 中的 dsh.bundle manifest
使其可用 dsh plugin add 安装):

从 npm registry(发布后)
dsh plugin --profile web add obsidian-dsh-acp

从本地发布产物(tarball)
dsh plugin --profile web add ./obsidian-dsh-acp-0.1.0.tgz

从本地检出(符号链接,开发模式)
dsh plugin --profile web add -w link:/path/to/dsh-acp

验证插件注册进 profile 的配置树:

dsh --profile web --dump-config | grep -A1 "dsh-acp"
-> # == obsidian-dsh-acp
- id: dsh-acp
name: obsidian-dsh-acp

插件读取 cordis.patch.yml,将 dsh-acp 条目插入到该 profile 的插件树中,然后暴露
dsh.acp 服务:

- ctx.get("dsh.acp") —— DshAcpService 实例。
- service.start() / service.stop() —— 启动 / 终止适配器子进程。
- service.process —— 存活的 ChildProcess(未运行时为 null)。

适配器环境变量

被拉起的 dsh --profile  进程读取这些环境变量。按需为适配器设置(Obsidian
custom-agent 的 env,或 profile/托管进程):

| 变量 | 含义 | 默认值 |
|----------|---------|---------|
| DSH_BIN | dsh 可执行文件 | PATH 上的 dsh |
| DSH_PROFILE | 启动使用的 profile | headless |
| DSH_ARGS | 提示词之前附加的参数(空格分隔) | (无) |
| DSH_ACP_LOG_DIR | 运行时日志目录 | (禁用) |
| DSH_ACP_LOG_MAX_BYTES | 日志轮转的大小上限(字节) | 5242880(5 MB) |
| DSH_ACP_LOG_KEEP | 保留的轮转 .1/.2… 日志份数 | 2 |
| DSH_ACP_STORE_DIR | 持久会话 JSON 索引目录 | ~/.dsh-acp |
| DSH_ACP_PERSIST_DEBOUNCE_MS | 索引合并写的防抖窗口(毫秒) | 100 |
| DSH_ACP_ARCHIVE_IN_MAIN | 将回合归档放到 sessions/ 而非 dsh-acp-archives/ | 0 |

配置(由 loader 提供):

cordis.patch.yml 条目的示例
- id: dsh-acp
name: dsh-acp
config:
spawn: true        # 在 app/ready 时启动适配器
profile: headless  # 适配器使用的 DSH profile
env: {}            # 适配器进程的额外环境变量

Headless profile 引导

dsh --profile headless 需要一个 headless profile 能够解析的默认模型提供商。如果全局
的 $DSH_HOME/settings.yaml 固定使用一个仅限 web 的提供商(例如
my-web-only-provider),请为 headless profile 提供它自己的设置:

- ~/.dsh/profiles/headless/settings.yaml —— 一条 llm-pi-ai 路由 +
agent-default-model。
- ~/.dsh/profiles/headless/cordis.patch.yml —— 通过 settings id 覆盖挂载该设置文件,
并设置 agent-default-model。

许可证

MIT

[acp]: https://github.com/evalstate/agent-client-protocol
[cordis]: https://github.com/cordiverse/cordis

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

💬 加入 DPharness 群聊

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

点击加入 QQ 群
DPharness 群聊二维码,手机 QQ 扫码进群
扫码进群