dsh-fish
Manifest validSelf-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/
🆕 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-guide | 0.2.2 | 在审批弹窗里追加中文说明:这次审批会做什么、有什么风险、依据是什么 |
dsh-git-sync | 0.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-order | 0.1.5 | 设置导航重排:把设置面板左侧菜单排成自己要的顺序、把不想看的项收起来;偏好随 Git 同步插件跨机复原 |
dsh-visual-companion | 0.1.7 | 视觉伴侣唤醒:网页上看原型 / 比布局,点选 + 备注后按「提交给助手」,会话自动收到一条用户消息并起一轮 —— 不必回终端复述;点选过程静默,只有提交才唤醒一次(0.1.7 起加载日志的版本号从 package.json 现读,不再写死) |
dsh-agent-teams-fish | 0.6.1 | AgentTeams 多智能体团队协作(上游 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-fish | 0.5.8 | 思考强度与输入模态(上游 HaoyueQin/dsh-better-reasoning-effort 的Fork):在官方「模型」页编辑卡里直接编辑每模型的 reasoningEfforts 与 input 声明,并支持一键自动适配;本 Fork 把 settings.models.provider-card 席位完整让给模型能力面板;0.5.8 并入上游三条安装路线说明(冷静期下写明版本号、release tarball 路线、GitHub 源码安装) |
dsh-our-free-model | 2.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 分发,著作权各归其上游原作者:
dsh-agent-teams-fish→ NanmiCoder/dsh-agent-teams(程序员阿江 / Relakkes)dsh-better-reasoning-effort-fish→ HaoyueQin/dsh-better-reasoning-effort(HaoyueQin)dsh-our-free-model→ Ebony-Vinyl/dsh-our-free-model(Ebony-Vinyl)
补充版的来源、署名与改动范围见各自仓库里的 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…