DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-fish

F

dsh-fish

Manifest valid

Self-used DSH (DeepSeek Harness) plugin bundle: a single pnpm workspace installs all 8 plugins (5 self-built + 3 upstream supplementary versions: AgentTeams / Thinking Intensity / Free Models), with sub-plugin source code located under packages/

hasBundlePatchMachine translated
@fish-under-sea/dsh-fish

@fish-under-sea/dsh-fish

一个包,装齐全部自建 DSH 插件

npm license node DSH bundle

简体中文 · English


🆕 0.7.8(2026-10-12):移出 @fish-under-sea/dsh-session-title-refresh,并新增自定义图标。

  • 为什么移出:DSH 自 v0.2.1-alpha.2 起已内置会话自动重命名,与该插件的核心用途重叠。该插件暂停维护更新(源码保留在 packages/ 下,npm 上已发布的版本仍可单独安装),本包不再随附。
  • ⚠️ 同时撤下一段 patch(要紧):原先本包会停用 DSH 内置的首行标题提供方(session-title-llm)为该插件让位。插件移出后这段停用必须一并撤掉 —— 否则内置提供方被停用却没有替代者,会话将不再自动命名。现在内置提供方恢复生效。
  • 仍要用旧插件:dsh plugin --profile <profile> add @fish-under-sea/dsh-session-title-refresh 照旧可装,它自带的 patch 会重新停用内置提供方。该包 README 顶部已加暂停维护说明。
  • 成员数 8 → 7;本包新增自定义图标 icon.png(384×384 · 231 KB,符合 DSH ≤256 KiB 的上限),插件管理器卡片与清单详情从此显示本包图标。

更早的版本记录见 CHANGELOG.md。


这是什么

Fish 自建 DSH(DeepSeek Harness)插件聚合包。根目录是聚合包,子插件源码在 packages/ 下。聚合包靠自己的 bundle 层(cordis.patch.yml)把七个插件的插件行一次性插入 profile 的 roster —— 其中四个是本仓库 packages/ 下的自建插件,另外三个是外部补充版:dsh-agent-teams-fish、dsh-better-reasoning-effort-fish 与 dsh-our-free-model(各自独立仓库,非本仓库子包)。

装一次 @fish-under-sea/dsh-fish = 装齐七个插件。

命名差异(容易踩):npm 包名 @fish-under-sea/* 带 scope,但仓库目录名(dsh-fish/)与 GitHub 仓库名(Fish-under-sea/dsh-fish)不带。

包含的插件

子包版本说明
dsh-approval-guide0.2.2在审批弹窗里追加中文说明:这次审批会做什么、有什么风险、依据是什么
dsh-git-sync0.4.0一键 Git 同步:把插件清单、启用状态、本地设置、Skills、看板/用量账本、设置导航顺序偏好、免费模型插件配置及用量账本与壁纸引擎整机配置快照($DSH_HOME/FISH.json,资产本体已内嵌)同步到自己的私有仓库。0.4.0 新增「导出私钥配置」:把带凭据的几份配置(channel-pack/ 的花名册 / 签到 / 账本、.credentials.yaml、our-free-model/eac-user.json)纯本机拷到指定目录(默认桌面)下的 DSH私钥配置 文件夹,并附一份说明 README —— 不碰 git、不发任何网络请求,凭据内容也不进日志;这条通路与 git 同步完全分开,因为凭据在同步硬黑名单里、永远不会随仓库走
dsh-settings-nav-order0.1.5设置导航重排:把设置面板左侧菜单排成自己要的顺序、把不想看的项收起来;偏好随 Git 同步插件跨机复原
dsh-visual-companion0.1.7视觉伴侣唤醒:网页上看原型 / 比布局,点选 + 备注后按「提交给助手」,会话自动收到一条用户消息并起一轮 —— 不必回终端复述;点选过程静默,只有提交才唤醒一次(0.1.7 起加载日志的版本号从 package.json 现读,不再写死)
dsh-agent-teams-fish0.6.1AgentTeams 多智能体团队协作(上游 NanmiCoder/dsh-agent-teams 的补充版):自然语言组队、成员/任务依赖 DAG、信箱通信、右侧栏树状监测;厂商头像素材随包分发(17 厂商 × 10 岗位 + 厂商通用图 + 立绘 + 队长 + 商标 SVG,286 个文件 / 约 29.3 MB,含 1024×1024 高清 WebP 族),装完即有,跨机不再依赖 artworkDir;自定义目录仍可整套覆盖;商标 SVG 按扩展名送达;队长头像跟随队长自己的模型路由;0.5.1 修掉降级链序(厂商+岗位 → 厂商 → 岗位);0.6.0 并入上游 v0.1.23(成员工具策略、质量门契约与修订绑定、lineage 身份沿 fork 链、工作区审计、损坏 team.json 降级);⚠️ 0.6.1 修掉「升级 DSH 到 0.2.1-alpha.2 后插件被整行禁用」 —— 该版本的宿主白名单此前未收录新运行时,DSH 判定不兼容并自动停用插件行(症状:显示「异常」、团队协作毫无反应)
dsh-better-reasoning-effort-fish0.5.8思考强度与输入模态(上游 HaoyueQin/dsh-better-reasoning-effort 的Fork):在官方「模型」页编辑卡里直接编辑每模型的 reasoningEfforts 与 input 声明,并支持一键自动适配;本 Fork 把 settings.models.provider-card 席位完整让给模型能力面板;0.5.8 并入上游三条安装路线说明(冷静期下写明版本号、release tarball 路线、GitHub 源码安装)
dsh-our-free-model2.1.0免费模型与渠道聚合(上游 Ebony-Vinyl/dsh-our-free-model 的Fork):把 13 个免费渠道(CodeArts / CodeBuddy / Loomy / Raccoon / MiniMax / Gemini 等)与免费模型并入官方模型选择器,并自带渠道网关供其它本地 harness 反代。本 Fork 新增「隐藏渠道模型分组」总开关 —— 渠道分组会与你自己配的 provider 混在一起把选择器撑长,打开即一次收起 13 组;只影响展示不影响路由(网关请求走 resolveModelInfo(),被隐藏的模型照常收发),渠道设置页的「显示列表 / 关闭全部」读 listAllModels() 也不受影响;默认关闭,升级不会静默改变你看到的列表。2.1.0 并入上游 v2.1.0 —— combos 组合链、token-saver 省 token、原生 Anthropic 网关、standalone 拆分、渠道包与 Kilo 渠道、升级器 snapshot SHA 修复;Fish 自建的隐藏渠道分组与按面积计价完整保留

本包不再停用任何内置插件

0.7.8 起的行为变化 —— 原先本包会显式停用 DSH 内置的会话标题提供方(session-title-llm),为 dsh-session-title-refresh 让位(会话标题服务每个进程只接受一个提供方,第二次注册直接抛错)。

该插件移出后,这段停用已一并撤除,内置提供方恢复生效。这一点很要紧:若只移出插件而保留停用,内置提供方被关掉却没有替代者,会话将不再自动命名。

仍要旧插件的用户单独安装即可,它自带的 patch 会重新停用内置提供方:

dsh plugin --profile <profile> add @fish-under-sea/dsh-session-title-refresh

安装

方式一:从 npm 安装(推荐,装一个包就够)

dsh plugin --profile <profile> add @fish-under-sea/dsh-fish

聚合包已声明七个插件依赖,它们作为传递依赖被 pnpm 装到 profile 顶层(本 profile 用 nodeLinker: hoisted),插件行按包名解析即可得到。

为什么不会插出重复行:对账逻辑(dsh-plugin-manager 的 reconcile)只遍历 profile 自己的 dependencies,不递归看传递依赖,所以子包不会被提升为 bundle 层,插行不会叠加。

⚠️ 如果安装报 [NOT_FOUND]:本包与七个成员包都已发布到 npm 官方源。若你的机器把 registry 指向国内镜像(例如 registry.npmmirror.com),镜像懒同步可能还没收录其中某个子包,于是 dsh plugin add 会以 404 Not Found … {"error":"[NOT_FOUND] @fish-under-sea/<子包> not found"} 失败。 这不是包不存在 —— 任选下面一条即可:

  • 触发镜像同步(公开端点、幂等、无需登录,等十几秒即可装):
    curl.exe -X PUT https://registry.npmmirror.com/-/package/@fish-under-sea/dsh-approval-guide/syncs
    curl.exe -X PUT https://registry.npmmirror.com/-/package/@fish-under-sea/dsh-git-sync/syncs
    curl.exe -X PUT https://registry.npmmirror.com/-/package/@fish-under-sea/dsh-settings-nav-order/syncs
    curl.exe -X PUT https://registry.npmmirror.com/-/package/@fish-under-sea/dsh-visual-companion/syncs
    curl.exe -X PUT https://registry.npmmirror.com/-/package/dsh-agent-teams-fish/syncs
    curl.exe -X PUT https://registry.npmmirror.com/-/package/dsh-better-reasoning-effort-fish/syncs
    curl.exe -X PUT https://registry.npmmirror.com/-/package/dsh-our-free-model/syncs
    
    返回 {"ok":true,"state":"waiting"} 即已受理;用 curl.exe https://registry.npmmirror.com/@fish-under-sea%2Fdsh-approval-guide 复查,出现 "latest" 就同步好了。
  • 或把该机器的 registry 换成官方源 https://registry.npmjs.org/。
  • 或用方式三的 link: 本地路径安装。

方式二:从 GitHub 安装(不想用 npm registry 时)

// profiles/<profile>/package.json
"dependencies": {
  "@fish-under-sea/dsh-fish": "github:Fish-under-sea/dsh-fish"
},
"devDependencies": {
  "@fish-under-sea/dsh-approval-guide": "github:Fish-under-sea/dsh-fish#path:packages/dsh-approval-guide",
  "@fish-under-sea/dsh-git-sync": "github:Fish-under-sea/dsh-fish#path:packages/dsh-git-sync",

  "@fish-under-sea/dsh-settings-nav-order": "github:Fish-under-sea/dsh-fish#path:packages/dsh-settings-nav-order",
  "@fish-under-sea/dsh-visual-companion": "github:Fish-under-sea/dsh-fish#path:packages/dsh-visual-companion",
  "dsh-agent-teams-fish": "github:Fish-under-sea/dsh-agent-teams-fish",
  "dsh-better-reasoning-effort-fish": "github:Fish-under-sea/dsh-better-reasoning-effort-fish",
  "dsh-our-free-model": "github:Fish-under-sea/dsh-our-free-model-fish"
}

#path: 是 pnpm 的子目录语法,让一个仓库同时提供多个包 —— 四个子包指向本仓库;三个外部补充版指向各自仓库:dsh-agent-teams-fish、dsh-better-reasoning-effort-fish 与 dsh-our-free-model(三者包都在各自仓库根目录,无需 #path:);换机 pnpm install 后直接从仓库下载,不依赖任何本机绝对路径。bundles 里只需列 "@fish-under-sea/dsh-fish"(它的 patch 负责插入八行)。

方式三:本地开发安装(改源码即时生效)

// profiles/<profile>/package.json
"dependencies": {
  "@fish-under-sea/dsh-fish": "link:<本仓库路径>"
},
"devDependencies": {
  "@fish-under-sea/dsh-approval-guide": "link:<本仓库路径>/packages/dsh-approval-guide",
  "@fish-under-sea/dsh-git-sync": "link:<本仓库路径>/packages/dsh-git-sync",

  "@fish-under-sea/dsh-settings-nav-order": "link:<本仓库路径>/packages/dsh-settings-nav-order",
  "@fish-under-sea/dsh-visual-companion": "link:<本仓库路径>/packages/dsh-visual-companion",
  "dsh-agent-teams-fish": "link:<dsh-agent-teams-fish 仓库路径>",
  "dsh-better-reasoning-effort-fish": "link:<dsh-better-reasoning-effort-fish 仓库路径>",
  "dsh-our-free-model": "link:<dsh-our-free-model-fish 仓库路径>"
}

不要用 file: 指向本仓库 —— pnpm 会把 file: 目录依赖当「无哈希的目录依赖」缓存,改了源码后 pnpm install(连 --force 也一样)不会重新复制,必须手动删掉 node_modules/dsh-* 再装。link: 没有这个问题。

装完重启 DSH 生效。

手工声明依赖时的两条坑

用方式一(npm)可跳过本节 —— 聚合包已替你处理好。

① 子包必须能被 profile 顶层解析到

DSH 的浏览器半区扫描器(@deepseek-ai/dsh-client-modules 的 locatePkgJson)按插件行里的包名去 profile 顶层解析包目录。行名必须是完整的包名:

  • ✅ 正确:@fish-under-sea/dsh-approval-guide(@scope/name 两段式 scoped 名)
  • ❌ 错误:多带一段子路径会被 exactPackageSpecifier() 判为「不是包」直接跳过

子包不在 profile 顶层时,行解析不到 package.json,插件的设置页与界面不会加载。

② 手工声明时子包要写在 devDependencies

dsh plugin 每次执行都会对账,把 profile 的 dependencies 里任何声明了 dsh.bundle 的包自动追加进 dsh.profile.bundles。七个包各自都声明了 dsh.bundle,而聚合包的 patch 已经把八行插行复述了一遍 ——

子包一旦被提升为 bundle 层,插行就会叠加成重复行,而重复挂载会让应用启动失败。

这一条对第七个成员 dsh-our-free-model 尤其要紧:它自己的 cordis.patch.yml 插入的 id 就是 our-free-model,与本包插的是同一个 id(composeEntries 只做 push、不去重)。所以任何时候都必须把它从 dsh.profile.bundles 里移走(或直接从 profile 的 dependencies 挪到 devDependencies)。

写在 devDependencies 同样会被装到 profile 顶层(行名照常解析得到),但不会被对账逻辑提升为 bundle 层。

子插件的运行期配置

本仓库四个子插件的参数都不写在 cordis.patch.yml 里,而是存在各自 $DSH_HOME 下的 config.json 中,在 GUI 设置页里修改(外部补充版与 dsh-visual-companion 相反:它们的配置写在插件行的 config 里):

插件设置入口配置文件
approval-guide无配置项—

| git-sync | 设置 → Git 同步 | $DSH_HOME/dsh-git-sync/config.json | | settings-nav-order | 设置 → 设置导航顺序 | 无配置项;偏好存在浏览器 localStorage(键 dsh-settings-nav-order/v1)并镜像到 $DSH_HOME/dsh-settings-nav-order/state.json(供 git-sync 采集) | | dsh-visual-companion | 无设置页(配置写在自己 profile patch 的插件行里) | 同上(watchDir:视觉伴侣根目录,用于「加载即自动绑定」) | | dsh-agent-teams-fish | 无设置页(配置写在聚合包 cordis.patch.yml 的插件行里) | 同上(stateDir / memberProvider / artworkDir) | | dsh-better-reasoning-effort-fish | 无设置页(能力直接嵌进官方「模型」页编辑卡) | 同上(autofill / modalityAutofill / probeTimeoutMs / bootRetryDelaysMs / defaultGuard,写在插件行的 config 或 settings.yaml 的插件 config 块) | | dsh-our-free-model | 设置 → 免费模型(含「偏好」区的隐藏渠道模型分组开关) | $DSH_HOME/our-free-model/settings.json(该文件在 git-sync 白名单里,跨机复原) |

配置目录名是不带 scope 的短名($DSH_HOME/dsh-git-sync/ 等),与 npm 包名解耦 —— 所以改包名不会动到已有配置。

外部补充版 dsh-agent-teams-fish 是例外:它的参数写在聚合包 cordis.patch.yml 的插件行 config 里(stateDir / memberProvider),另有 artworkDir 用于指向自定义美术目录:

- id: agent-teams
  name: 'dsh-agent-teams-fish'
  config:
    stateDir: .agent-teams        # 团队状态目录(相对会话工作区)
    memberProvider: spawn         # 成员派生方式:spawn 或 fork
    # artworkDir: <绝对路径>      # 可选:自定义头像/商标目录(机器相关,默认用包内美术)

artworkDir 是机器相关的绝对路径,所以没有写进聚合包(换机器不会指到别人的目录);需要自定义美术时,在自己 profile 的 patch 层覆盖同一个 id: agent-teams 行即可。

关于 settings-nav-order

设置面板左侧那列菜单(通用设置 / 模型 / 内置插件 / Agent 预设 / …)的顺序,本来写死在每个插件自己的 settings.section 注册里(一个 order 数字),GUI 里既没有重排入口,也没有收起不用的办法。本插件加一页「设置导航顺序」解决:

  • 排序:拖动 ⋮⋮ 把手,或点 ↑/↓
  • 隐藏:点「隐藏」收起不想看的项
  • 做法:给导航按钮打 CSS order(容器是 flex column)、隐藏打 display:none(节点不删,随时可逆)—— 两者都不动 DOM 顺序、不改任何第三方插件代码,所以插件升级不会冲掉这些偏好
  • 数据:主副本在浏览器 localStorage(键 dsh-settings-nav-order/v1),另由宿主半区镜像到 $DSH_HOME/dsh-settings-nav-order/state.json —— 该文件在 git-sync 的白名单里,所以顺序与隐藏项会跟着配置仓跨机复原(换机打开设置页即自动回填)。0.1.2 起如此;此前这些偏好只在浏览器里,不跟仓库走
  • 保存后如实回报:面板会写明宿主文件是否已同步(写不进去就说「未同步、下次自动重推」,不假装成功);有未保存的排序时点「启用」开关,也仍然显示「未保存」,不会谎报「已保存」
  • 退回原样:关掉「启用手动排序与隐藏」,或点「恢复默认」
  • 防自锁:「设置导航顺序」这一页不能隐藏自己 —— 它是唯一能取消隐藏的入口
  • 识别方式:真实类名是 CSS Modules 哈希名(ZiQlkq_navList),所以按 [class*="navList"] 子串匹配,DSH 换哈希前缀也不受影响

仓库结构

dsh-fish/                 # 仓库目录名(npm 包名是 @fish-under-sea/dsh-fish)
├── package.json          # 聚合包清单(version 0.7.6,dsh.bundle.patch 指向 cordis.patch.yml)
├── cordis.patch.yml      # bundle 层:插入七个插件的插件行
├── CHANGELOG.md          # 完整版本记录(README 顶部只留最近一版)
├── pnpm-workspace.yaml   # workspace 声明(仅本地开发用)
├── lib/                  # 聚合包自身的空实现(本包不注册任何东西)
│   ├── index.js
│   └── client.js
└── packages/
    ├── dsh-approval-guide/

    ├── dsh-git-sync/
    ├── dsh-settings-nav-order/
    └── dsh-visual-companion/

三个外部补充版 不在 packages/ 下 —— dsh-agent-teams-fish 的源码在它自己的仓库,dsh-better-reasoning-effort-fish 在另一个仓库,dsh-our-free-model 在第三个仓库;三者都以 npm 依赖的形式随聚合包装到 profile 顶层。

子包为什么不在聚合包的 files 里被打包进来:聚合包只携带 lib/、cordis.patch.yml 与 README*.md,四个子包与三个外部补充版都以 npm 依赖的形式被装到 profile 顶层(见方式一)。只有在「一个仓库同时提供多个包、从 GitHub 安装」时才需要在安装方 profile 里用 #path: 显式声明(见方式二)。

开发

pnpm install                                                          # 装 workspace 依赖

node packages/dsh-approval-guide/test/guide.test.mjs                  # 跑测试

node packages/dsh-git-sync/test/client.test.mjs
node packages/dsh-git-sync/test/test-sync-engine.mjs
node packages/dsh-git-sync/test/commit-identity.test.mjs
node packages/dsh-settings-nav-order/test/client.test.mjs
node packages/dsh-settings-nav-order/test/host.test.mjs
node packages/dsh-visual-companion/test/visual-companion.test.mjs

聚合包本身不实现功能,也不注册任何东西 —— 它的唯一职责是携带 cordis.patch.yml。

改包名时要同步的五处

包名不只是 package.json 里的一行字符串,五处必须一起改,漏一处就在运行期炸:

#位置漏改的后果
1六个 package.json 的 name安装方的依赖键对不上
2聚合包与四个子包 cordis.patch.yml 里的行 name行解析不到包,插件整条不加载
3⚠️ 带浏览器半区的包(本仓库四个子包 + 两个外部补充版)lib/client.js 里 __ModuleLoader__.load({ id }) 的 id浏览器侧报 loaded without registering "<包名>",插件加载失败
4安装方 profile 的依赖键与 bundles依赖装不上、bundle 层不展开
5子包在 profile 里的归属必须放 devDependencies(见「两条坑」第 ② 条)

第 3 条最隐蔽:loader 是拿行里解析出的包名去 factories 里认领 factory 的(@deepseek-ai/dsh-client-modules/lib/client.js 的 if (!this.factories.has(id)) throw ... loaded without registering),所以注册名必须严格等于包名 —— 包名带 scope,注册名也必须带。

好消息:四个带浏览器半区的子包的客户端测试都断言了这一点,而且断言读的是 package.json 的 name 而不是硬编码字符串 —— 以后再改名漏改,会被测试直接抓住。

外部补充版同理:dsh-agent-teams-fish(仓库)、dsh-better-reasoning-effort-fish(仓库)与 dsh-our-free-model(仓库)都来自独立仓库,改包名时同样要同步 package.json 的 name / cordis.patch.yml 的行 name / lib/client.js 的注册 id 三处 —— 前者的美术路由链测试断言「注册名 = package.json 的 name」,后者的常量 PLUGIN_ID 也等于包名(src/constants.ts),改名漏改同样会被抓住。

许可

MIT(聚合包与四个子包一致)。

三个外部补充版同样以 MIT 分发,著作权各归其上游原作者:

补充版的来源、署名与改动范围见各自仓库里的 NOTICE.md。

仓库根目录已放置 LICENSE 文件,与 package.json 中的 license 字段(MIT)及四个子包保持一致。


聚合包 @fish-under-sea/dsh-fish v0.7.9 · DSH ≥ 0.2.0-rc.2 · Node ≥ 20

Comments

Loading…