2384418321/dsh-integration-settings

dsh-integration-settings

在 DSH 设置里加两个可视化页面。MCP 管理以 JSON 为真理源整体重写 profile patch 受管区块(写入前做 YAML 校验与时间戳备份),并支持粘贴 mcpServers JSON、先列出将新增/将覆盖的条目再写入。思考解锁对每个 OpenAI 兼容网关探测它真正声明的思考档位并逐模型写回,手写的其他 YAML 片段逐字节保留;可用模型清单由独立按钮同步,先预览将新增/将移除,确认后与思考档位同批写入,也可绑定页面上的定时更新。

Uncategorizedagents-mdai-agentdeepseek-harness

dsh-integration-settings

简体中文 | English

给 DeepSeek Harness(DSH)设置里补上两个可视化菜单:MCP 管理 与 思考解锁。后者把平时只能手改文件的事变成点选操作——自动识别每个 OpenAI 兼容网关真正支持的思考档位并写回模型选择器,也能设成定时自动更新。

本仓库是本地分叉版(版本号带 -dsh.N 后缀)。与上游的差别见 LOCAL-PATCH.md:
上游的 Skill 管理 与 全局人设 两个菜单已在本分叉移除(相关后端接口仍在,只是没有 UI 入口);
思考档位解锁 与 可用模型清单 已彻底拆成两件事,分别由「思考解锁」开关和独立的「同步模型清单」按钮负责。

设置菜单 · 管什么 · 背后落盘位置 MCP 管理 · 增 / 删 / 改 / 启停 MCP 服务器;支持粘贴 mcpServers JSON 先预览再新增 · 当前 profile 的 cordis.patch.yml(受管区块)+ .dsh-integration/mcp.json(真理源) 思考解锁 · 打开即自动识别每个网关真正支持的思考档位,一键解锁写回配置;可新增/编辑网关(不提供删除) · 当前 profile 的 cordis.patch.yml(llm-pi-ai 条目的 config.providers)+ $DSH_HOME/.credentials.yaml(refs,只存密钥) 同步模型清单 · 独立按钮,与「思考解锁」开关语义分离:先预览「将新增 N 个 / 将移除 M 个」再确认;一次同步同时刷新思考强度等级与可用模型列表,两者同批生效;可与页面「定时更新」绑定同一调度(定时触发自动确认,并在 UI 提示上次差异摘要) · 同上(config.providers 的 levels 与 models)+ $DSH_HOME/.dsh-integration/unlock-schedule.json(定时状态与上次同步摘要)

这是社区插件,不是 DeepSeek 官方产品。安装前请自行评估,建议先备份 profile 目录。

环境要求

  • DSH 桌面版 0.2.0-rc.2(本插件按该版本的 settings.section 槽位与 loader patch 机制开发;

宿主包名从此版本起为 @deepseek-ai/*)。

  • Node.js `^22.19.0 || >=24`:仅在本地构建 / 跑测试时需要;直接安装不需要 Node,

因为仓库里已提交构建产物 lib/。

  • 安装完成后必须重启 DSH:MCP 改动由 loader 在启动时读取(技能、人设改动即时生效)。

安装

两种方式任选其一;下面用 desktop profile 举例,换成你自己的 profile 名即可 (DSH 桌面版的默认 profile 就是 desktop)。

想直接把安装交给另一台电脑上的 AI? 把仓库地址和
INSTALL.zh-CN.md 一起发给它即可——那是一份逐条带「期望输出」的可执行
runbook(环境探测 → 安装 → 重启 → 验证 → 网关配置 → 定时验收 → 故障排查 → 验收清单)。

方式 A:从 GitHub 安装(推荐)

# dsh CLI 在 DSH 应用目录里:
#   macOS        /Applications/DeepSeek Harness.app/Contents/Resources/runtime/cli/bin/dsh
#   Windows 等   <DSH 安装目录>/resources/runtime/cli/bin/dsh(Windows 上是 dsh.cmd)
# 若已把 dsh 加入 PATH,直接写 dsh 也行;布局不同时可在安装目录里搜 runtime/cli
DSH="/Applications/DeepSeek Harness.app/Contents/Resources/runtime/cli/bin/dsh"

# 1) 安装:会登记依赖并把包名追加到 profile 的 dsh.profile.bundles
"$DSH" plugin --profile desktop add github:2384418321/dsh-integration-settings

# 2) 确认已登记(列表里出现 dsh-integration-settings 即成功)
"$DSH" plugin --profile desktop list

仓库直接提交了 lib/ 构建产物,所以从 GitHub 安装既不需要 npm 发布,也不需要本地构建。

方式 B:从本地目录安装(改源码调试用)

git clone https://github.com/2384418321/dsh-integration-settings.git
cd dsh-integration-settings
DSH="/Applications/DeepSeek Harness.app/Contents/Resources/runtime/cli/bin/dsh"
"$DSH" plugin --profile desktop add "$(pwd)"    # 本地目录以 link: 形式登记

以 link: 登记时,本分叉没有 src/ 与构建脚本:直接改 `lib/index.js` / `lib/client.js`,再重启 DSH 即可,不必重装。

方式 C:绕开 dsh CLI 手工登记

  1. 在 profile 目录里安装(profile 目录:$DSH_HOME/profiles/):
cd "$HOME/.dsh/profiles/desktop"
   pnpm add github:2384418321/dsh-integration-settings
  1. 确认该目录 package.json 的 dsh.profile.bundles 数组里有

"dsh-integration-settings"(缺了就手工追加到数组末尾)。

  1. 重启 DSH。

安装完成后怎么确认

  1. DSH 重启后,设置(Settings)左栏底部出现两项:MCP 管理 / 思考解锁。
  2. 打开「MCP 管理」,页面上方的 profile 徽标应显示你要操作的那个 profile 名;

多 profile 场景下先核对徽标,再动手改。

  1. 已有 MCP 服务器应被列出;cordis.patch.yml 里手写但未被纳管的行会以横幅提示,可一键导入。

卸载

DSH="/Applications/DeepSeek Harness.app/Contents/Resources/runtime/cli/bin/dsh"
"$DSH" plugin --profile desktop remove dsh-integration-settings

再从 profile 的 dsh.profile.bundles 里删掉本包名,并(可选)清理 profile 的 cordis.patch.yml 中 # >>> dsh-integration-settings:managed:mcp 到 # <<< dsh-integration-settings:managed:mcp 之间的受管区块。

故障排查

现象 · 原因 / 处理 页面所有接口 404(定时更新状态读取失败:请求失败(HTTP 404)),且插件状态是 pending · 宿主 inject 声明了运行时不存在的服务:cordis 等不到服务,fiber 永远停在 pending,apply() 不执行 ⇒ 路由根本没注册。0.2.6 及更早版本在 webRuntime 被新版 DSH 删除后即触发此问题 · 升级到 0.2.7 及以上(inject 已收成 ['webServer','sessions']),然后完全重启 DSH ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED · pnpm 11 默认不执行 git 依赖的 prepare · 在 profile 的 pnpm-workspace.yaml 加 allowBuilds: + '': true,再重跑安装 sh: npm: command not found / spawnSync npx ENOENT · 该 profile 里有依赖的 prepare 要跑 npm install,而这台机器没有 npm/npx · 装 Node.js(自带 npm/npx)后重试;细节见 INSTALL.zh-CN.md 第 7 节 装完了,设置里没有这两个菜单 · ① 确认 list 与 profile package.json 的 dsh.profile.bundles 里有本包名;② 确认重启的是同一个 profile;③ 若 bundle 加载失败,DSH 启动时会往 stderr 打 : skipping profile bundle "dsh-integration-settings": 并静默跳过——常见原因是 lib/ 缺失(构建产物未随仓库提供)、Node 版本过低或依赖解析失败 点进菜单一片空白 · settings.section 是 root scope 槽位,一旦在条目里调用 seat 上的 session hook(usePanelInfo 等)就会触发 Minified React error #311,shell 会把整个槽位替换成 `。改客户端代码时请守「root scope 条目不调用任何 seat hook」这条(见下方设计要点) MCP 改了不生效 · profile patch 由 loader **启动时**读取:重启 DSH 后生效(页面上也有提示)。技能、人设改动即时生效 写操作报 403 / 415 · 宿主路由要求写请求带 x-dsh-integration: 1 与 application/json;非 loopback / 不可信 Host、Origin 与 Host 不一致、Sec-Fetch-Site: cross-site 一律 403 patch 写坏了想回滚 · 每次写入前都会在 profile 目录留时间戳备份(保留 3 份),改名覆盖回去即可;也可以只删掉两行标记之间的受管区块 页面报 ambiguous_profile · 有多个 profile 的依赖里含本插件,无法唯一确定。用页面上的 profile 选择器指定,或设置 DSH_PROFILE_DIR / 传 --profile `

数据与隐私:插件不内置任何凭据。密钥请按下面的写法引用环境变量(!!js process.env.X), 不要明文写进 patch;.dsh-integration/ 是你的本机数据,已在 .gitignore 里排除。

设计要点

MCP 管理

DSH 没有「MCP 注册表」这种东西:一个 MCP 服务器就是 profile patch 里的一条 loader 行。

- insert:
    - id: mcp-github
      name: '@deepseek-ai/dsh-mcp-client'
      config:
        serverName: github                              # 工具名 => mcp__github__<tool>
        transport: stdio                                # stdio | streamable-http
        command: npx
        args: ['-y', '@modelcontextprotocol/server-github']
        env: { GITHUB_TOKEN: !!js process.env.GITHUB_TOKEN }
  • 因为「新增未知 id 的 patch 条目」只有 - insert: 一种合法写法,所以本插件把

受管区块整体重写:JSON(.dsh-integration/mcp.json)是真理源,区块每次由它重新生成。

  • 区块用两行标记注释包夹,cordis.patch.yml 里其它手写内容原样保留;写入前做 YAML 结构校验 +

时间戳备份(保留 3 份)。

  • 已经在 patch 里手写、但插件还不认识的 MCP 行会在页面上以横幅提示,可一键导入纳管。
  • !!js 表达式(例如 !!js process.env.GITHUB_TOKEN)在往返编辑中不会丢失,密钥不会落盘:

env / headers 的任意层级值、以及 args 中以 !!js 开头的元素都会被写成真正的 YAML 标签 (TOKEN: !!js process.env.GITHUB_TOKEN),普通字符串则保持原样;读回时又是字符串,往返无损。

  • 若 profile 的 patch 文件是模板里的 [] 空占位,插件会在写入受管区块前先丢掉这行占位,

避免生成 Unexpected seq-item-ind token 这类非法 YAML。

改的是哪个 profile?

按以下顺序解析,尽量不猜(顺序:权威 → 显式 → 推断):

  1. 宿主服务 ctx.get('desktopProfiles').current.dir(桌面版里就是当前真正在用的 profile,最权威);
  2. 环境变量 DSH_PROFILE_DIR;
  3. --profile / --profile= 参数或 DSH_PROFILE 环境变量(该 profile 目录需存在);
  4. 扫描 $DSH_HOME/profiles/*,找唯一一个依赖里含本插件的 profile;
  5. 有多个候选时优先 desktop;仍无法唯一确定则报 ambiguous_profile 并提示手动指定,不会瞎写。

可在页面上方的 profile 徽标确认当前操作对象。

设置页 seat 里的坑(改这个插件前必读)

settings.section 是 root scope 槽位。shell 给每个条目的 props 里塞了一整套 seat 分享: usePanelInfo、useSessions、useSessionStatus、useWorkspaces、useResource、 useSessionRetainInfo、renderFactorySlot、t、close。

  • **这些 use* 在 root scope 条目里调用会抛异常**(它们属于 session scope)。一旦把调用包在

try/catch 里把异常吞掉,React 的 hook 链就错位了,下一次渲染会在组件里第一个 useState 处抛 Minified React error #311;shell 有 per-entry 错误边界,会把整个 slot 换成 ` —— 用户看到的就是「点进去空白」。 所以:**root scope 条目绝不调用 seat 上的任何 hook**,只用普通 prop(本插件的 sessionIdOf 只读 props.sessionId`)。

  • 更不能让 hook 调用顺序依赖 props 形状(第二个渲染时 props 变了 → "more/fewer hooks than

during the previous render",同样白屏)。

  • test/client-hooks.test.js 专门守这两条:用计数版 React 直接驱动组件函数,断言 seat 上的

session hook 一次都没被调用、且两套不同 props 下 hook 序列完全一致。改组件时别绕过它。

  • 需要一次渲染看不出来的 bug 时,renderToString 抓不到 hook 顺序变化;上游会用

DSI_DEBUG=1 node scripts/build.mjs 出不压缩、保留函数名 + 内联 sourcemap 的客户端包,再用无头 Chrome 打开真实 GUI 看控制台栈。本分叉没有构建链,需要在 lib/client.js 里自行定位。

(上游的)Skill 管理 / 全局人设 — 本分叉已移除

lib/client.js 的注册数组现在只保留 integration-mcp 与 integration-providers,所以这两个 页面的 UI 入口已经不存在;后端接口 /skill/*、/persona/* 仍在(组件函数也还在 bundle 里), 只是没有入口。上游版本用它们浏览/新建/编辑技能(目录下带 YAML frontmatter 的 SKILL.md)和可视化 编辑 $DSH_HOME/AGENTS.md 人设文件;这些能力本分叉没保留 UI,需要时直接手改文件。

思考解锁

DSH 的模型供应商由 @deepseek-ai/dsh-llm-pi-ai 的 config.providers 决定,写在各 profile 的 cordis.patch.yml 里。思考档位(reasoningEfforts)一旦声明就是白名单:没声明的档位在模型 选择器里就是灰的,所以「这个模型能不能选 High / Max」完全由那几十行 YAML 决定。

本页有两个互不绑定的入口,这是本分叉相对上游最重要的语义修正:

入口 · 只负责 · 落盘字段 「思考解锁」开关 / 「全部解锁」按钮 · 思考强度等级(reasoningEfforts / levels) · config.providers[*].levels 「同步模型清单」按钮 · 可用模型列表(models),并连带刷新等级 · config.providers[*].models + levels

自动识别(只读,不改文件)

  • 打开页面即自动探测:对每个被判定为网关的供应商发一次只读的 GET /models,读出

reasoning_supported_efforts / can_disable_thinking,逐模型与当前配置比对,页面显示 「待解锁 N / 已一致 M / 网关未声明 K / 网关已不提供 G」。识别阶段不写任何文件。

  • 按形态自动判断,不写死名字:只处理同时满足「api 为空或 openai-completions」+

「baseURL 是 http(s) 地址」+「apiKeyEnv 的凭据在 $DSH_HOME/.credentials.yaml 的 refs: 里 或存在同名环境变量」的供应商。其余在页面上标出跳过原因(api 不是 OpenAI 兼容 / 地址不可解析 / 凭据缺失),既不探测也不改写。

  • 只碰这个条目的 `config.providers`:- id: llm-pi-ai 以外的条目一律不读不写。DSH 自带的

deepseek-official / deepseek-account 不在这个文件里,插件碰不到。