Back to home

Eidosiny

dsh-accessory-hub

配件中心(Accessory Hub):DSH Web GUI 悬浮卡片插件 —— 可拖动/可缩放,聚合插件、MCP、预设、技能卡片,支持自定义显示名与颜色、彩色关系连线、确认注入"请使用xxx"前缀。A floating-card plugin for the DeepSeek Harness Web GUI.

Stars
1
Language
JavaScript
Created
Aug 16, 2026
Updated
Aug 16, 2026

Introduction

配件中心(Accessory Hub)

English · Security

DSH(DeepSeek Harness)Web GUI 悬浮卡片插件:右上角折叠圆形(DeepSeek 鲸鱼图标)→ 点击展开浅色便签纸风格画布(米黄格子底 + 便签卡片)。

只显示你手动添加的配件(插件 / MCP 服务 / Agent 预设 / 技能,DSH 自带配件不会自动上画布),支持:

  • 自定义显示名与颜色
  • 彩色连线表示附属 / 兼容关系(可点击编辑、删除)
  • 选中卡片高亮关联连线、其余变暗
  • 底部「确认使用」:在下一条用户消息开头注入「请使用<显示名>」前缀(如 请使用llm-vision-mcp 分析一下这张图片
  • 悬浮卡本体可自由拖动(圆形 / 标题栏,位置联动记忆)、右下角手柄自由调节尺寸
  • 所有自定义持久化于 DSH_HOME/accessory-hub/state.json,刷新/重启后保留

安装

要求

  • DeepSeek Harness(@deepseek-ai/dsh)web profile 已可运行(dsh --profile web
  • Node.js 环境(DSH 自带)

方式一(推荐):cordis.patch.yml 显式装配

  1. 把本仓库放到 web profile 的 vendor 目录(确保 lib/index.jslib/client.js 存在):

    git clone https://github.com/Eidosiny/dsh-accessory-hub.git \
      <DSH_HOME>/profiles/web/vendor/dsh-accessory-hub
    
  2. 编辑 <DSH_HOME>/profiles/web/cordis.patch.yml,追加一个插件行:

    - insert:
        - id: dsh-accessory-hub
          name: '@dsh-external/dsh-accessory-hub'
          config: {}
    
  3. 重启 web:dsh --profile web(或你的启动方式),然后刷新浏览器页面(客户端 bundle 在页面加载时装配)。

  4. 右上角出现鲸鱼圆形按钮即安装成功。

方式二:super-injector 运行时注入(免重启)

在 DSH 会话中使用超模注入器(dsh-super-injector)提供的 dev_inject_plugin 工具,或在其设置页「插件」中拖入 / 输入插件目录路径后「注入」:

dev_inject_plugin <本仓库绝对路径>

⚠️ 常见错误:不要加进 dsh.profile.bundles

本包只声明 dsh.client(客户端注入包),没有 dsh.bundle.patch。把它写进 profiles/web/package.jsondsh.profile.bundles 会让 dsh web 启动即失败

Error: dsh: profile bundle "@dsh-external/dsh-accessory-hub" declares no dsh.bundle in its package.json

客户端 bundle 的正确装配路径是 cordis.patch.yml 插件行(方式一):client-modules 会扫描 loader entries 中声明 dsh.client.platform: "web" 的包,自动把 exports["./client"] 指向的 bundle 挂到 /plugins/<id>/client.js 并在页面加载时注册。

结构

  • lib/index.js — 宿主侧插件:提供 GET/POST /accessory-hub/api/* REST API(配件枚举 + 自定义状态持久化;skills 带文件系统兜底枚举 DSH_HOME/skills/;MCP 服务单独归类:检测 config.serverName 的 loader 条目 → mcps 数组,含 transport/url/command/args)。
  • lib/client.js — 客户端 bundle:shell.overlay 槽位注册 React FC(浅色主题、米黄格子画布、添加/删除配件、拖动、编辑、连线、高亮、前缀注入)。
  • package.json — 包元数据 + dsh.client 客户端注入声明。

使用

  1. 点右上角圆形按钮展开面板(悬浮卡可自由拖动且位置联动:折叠态拖圆形按钮、展开态拖标题栏 ⠿,两者共用同一位置锚点——面板默认从圆形向左展开(右上角钉在圆形右上角),拖任意一方另一方跟随,位置自动记忆);面板尺寸可调:拖右下角 ⤡ 手柄自由缩放(最小 360×280,上限视口),尺寸同样持久化;
  2. 「+ 添加配件」从目录(插件 / MCP / 预设 / 技能,可搜索、按类过滤)选择要上画布的配件;MCP 服务按 serverName 列出(如 visionplaywright),描述显示传输方式与端点(stdio · npx -y @me9rez/llm-vision-mcp 等),可改名(如 llm-vision-mcp);
  3. 画布上拖动排布、✎ 编辑显示名与颜色、删除卡片(✎ → 删除卡片,关联连线自动清理);
  4. 「连线模式」点两张卡建立关系(附属=实线/兼容=虚线,颜色取起点卡色),点线可改关系/颜色/删除;
  5. 点击卡片选中(关联线高亮、其余变暗),底部「确认使用」把「请使用<显示名>」注入输入框草稿开头(无当前会话时提示)。

宿主 API

方法路径说明
GET/accessory-hub/api/catalog{ ok, plugins:[{id,name,active}], mcps:[{id,name,transport,url,command,args,active}], presets:[{id,name,description,broken}], skills:[{name,description,provider}], warnings }
GET/accessory-hub/api/stateDSH_HOME/accessory-hub/state.json,不存在/损坏回 {}
POST/accessory-hub/api/statebody { state: {...} },浅校验后原子写回(tmp + renameSync)

持久化状态 schema:{ version, plugins, presets, skills, mcps, edges, ui },各配件 section 以配件 id 为键存 { label, color, x, y }edges 存关系连线,ui 存悬浮卡位置与面板尺寸。原子写复用 tmp + renameSync 模式。

安全性

详见 SECURITY.md。要点:

  • 无远程网络请求:宿主侧只使用 Node 内置模块,不发起任何对外 HTTP;客户端只请求同源 /accessory-hub/api/*
  • 无任意代码执行:无 eval / new Function / 子进程 / shell。
  • 无 XSS:客户端全部通过 React 文本节点渲染(无 innerHTML/dangerouslySetInnerHTML),卡片名、目录描述等输入均被转义。
  • 本机隔离:API 只绑定 DSH web 的回环地址(默认 127.0.0.1),响应不带 CORS 头 → 跨源网页无法读取或写入。
  • 写入受限:POST /state 有 2MB 体积上限 + 浅校验,只写固定路径 DSH_HOME/accessory-hub/state.json(原子 tmp+rename),无路径穿越面。
  • 数据面最小:只读 loader 条目 / 预设 / 技能目录的元数据(名称、描述),不读取文件正文(技能仅读 SKILL.md 首行做描述)。

服务注入

宿主侧:webServerloaderagentPresetsskills

客户端侧(dsh.client.inject):@deepseek-ai/dsh-client-runtime@deepseek-ai/dsh-client-ui-layout@deepseek-ai/dsh-client-ui-conversation