dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
面向 DeepSeek Harness(dsh)的**第三方插件管理器**:在 Web UI 设置页选择第三方插件库文件夹,搜索其中所有第三方插件,并一键关闭/启动(刷新 dsh 后生效)。
面向 DeepSeek Harness(dsh)的第三方插件管理器:在 Web UI 设置页选择第三方插件库文件夹,搜索其中所有第三方插件,并一键关闭/启动(写入 cordis.patch.yml 的 disabled 标记,重启 dsh 后生效)。
本插件本身也是一个第三方插件,挂载到 host composition 后,启动 dsh 即默认加载。
dsh-plugin-manager/
├── package.json # npm 包:exports + dsh.client + dsh.bundle
├── dsh.plugin.yaml # DH-TP-SDK manifest
├── cordis.patch.yml # 挂载参考:host composition insert row
├── install.ps1 # Windows 一键安装(junction + patch insert,幂等)
├── install.sh # POSIX 一键安装(symlink + patch insert,幂等)
├── README.md / design.md
├── lib/client.js # Client 半体:factory-form bundle(设置页「第三方插件」)
└── src/
├── index.js # 入口 → host.js
└── host.js # Host 半体:webServer 路由 scan / toggle / statusPOST /dsh-plugin-manager/scan — 扫描指定文件夹中的第三方插件项目(识别 dsh.plugin.yaml / package.json,跳过 node_modules/.git/dist 与 DSH 自身)。POST /dsh-plugin-manager/toggle — 关闭/启动某个插件(写 cordis.patch.yml 的 disabled: true,写前自动备份 .bak)。GET /dsh-plugin-manager/status — 返回当前 patch 路径与各插件启停状态。本插件是 npm 包 + host composition row 形态:设置页「第三方插件」全局加载,重启后自动加载。
下载后,在插件目录内运行对应脚本,即可自动完成「链接进 node_modules + 写入 cordis.patch.yml」两步:
Windows(PowerShell)
git clone <你的仓库> dsh-plugin-manager
cd dsh-plugin-manager
powershell -ExecutionPolicy Bypass -File install.ps1Linux / macOS(bash)
git clone <你的仓库> dsh-plugin-manager
cd dsh-plugin-manager
bash install.sh脚本是幂等的(重复运行无害)。装完后重启 dsh(Ctrl+C 后重新 npx dsh web / dsh web),即完整可用:「设置 → 第三方插件」出现设置页(选文件夹扫描第三方插件、启停)。
$DSH_HOME/profiles/node_modules/dsh-plugin-manager -> 本目录($DSH_HOME 默认 ~/.dsh;Windows 用 junction,Linux/macOS 用 symlink。或发布到 npm 后 npm install dsh-plugin-manager 亦可。)
$DSH_HOME/profiles//cordis.patch.yml 追加:- insert:
- id: dsh-plugin-manager
name: 'dsh-plugin-manager'(profile 默认 web,可用环境变量 DSH_PROFILE 覆盖;DSH home 可用 -DshHome 参数或 DSH_HOME 环境变量覆盖。)
提示:Host 半体(webServer 路由)改cordis.patch.yml后热生效;Client 半体(设置页)在 boot 时由dsh-client-modules扫描加载,需重启后刷新页面。
每个第三方插件都挂到同一份 cordis.patch.yml / node_modules,必须保证以下全局唯一,否则会相互覆盖或注册报错:
命名对象 · 约定(本插件取值) · 冲突后果 包名 / row id / 设置页 slot id · dsh-(dsh-plugin-manager) · 同名 → node_modules 链接与 patch row 互相覆盖 HTTP 路由前缀 · //(/dsh-plugin-manager/scan 等) · 同名路由注册会 throw
install.ps1 / install.sh 是各自仓库根目录的普通文件,用户在各自的 clone 目录里执行,不会互相冲突;只要坚持「一个插件一个唯一前缀」,多插件共存安全。
dsh-client-modules 只扫描 host Loader entries,且 client UI 是 boot 时加载的全局 UI,agent preset 的 client 不会被加载。profiles/node_modules 可解析(junction 或安装),否则 Cordis 无法 import。pickDirectory() 依赖官方目录选择器服务;不可用时回退手动输入路径。本插件从「写出来」到「真的跑起来」经历了三次重启排查。以下结论均在真实 dsh 上验证过,写新 host 平面插件可直接复用。
服务 · host 平面可用? · 正确用法 webServer · ✅ · 必须 `inject: ['webServer']` 硬依赖 + `ctx.webServer`。它由 webserver entry 异步依赖驱动(inject: [webStartup] → cmdlineArgs),用 ctx.get('webServer') 会在 apply 时拿到 undefined(apply 先于 webServer 提供执行)。官方 dsh-client-modules 也是 static inject = ["webServer", "loader"] loader · ✅ · ctx.get('loader')(可选读取,判空)。loader 是 host 平面根服务,apply 前必已存在 fs · ❌ · ctx.get('fs') 返回 undefined。fs 是 per-agent 服务(SandboxedFileSystem 注入 sandboxPolicy,且 Service[symbols.filter] 按 isolate realm 过滤)。替代:直接用 `node:fs`(官方 dsh-fs-local 自己就 import node:fs)
SandboxedFileSystem 注入 sandboxPolicy 且带 isolate realm 过滤),在 host composition 全局 context 中返回 undefined。这也是 dsh-plugin-design 的 Host 半体挂 host composition 后 dshpd_* 工具从未注册成功的根因。本插件用 import { readFileSync, writeFileSync, readdirSync } from 'node:fs'。webserver entry 异步依赖驱动(inject: [webStartup] → cmdlineArgs),用 ctx.get('webServer') 会在 apply 时拿到 undefined。Panel)内部不能直接引用 `ctx`(闭包中不存在,会 ReferenceError)。须在 apply(ctx) 内先取服务(如 ctx.get('workspaces')),再通过 props 传入组件。dsh-client-modules 只扫描 host Loader entries,浏览器 boot 时按 window.__DSH_BOOT__ 加载全局 UI;agent preset 的 client 不会被加载。host.call,用 fetch('/dsh-plugin-manager/...')。console.error('[dsh-plugin-manager] ...') 是第一个信号源。dsh --profile web --dump-config:确认 patch row 是否被正确 compose。Get-Content 默认 GBK 读 UTF-8 会显示乱码,用 read 工具或 -Encoding UTF8 确认真实内容。完整推演、源码级机制与最终验证清单见 design.md 第 11 节。