Back to home@countossbot

dsh-skill-injector

Auto-inject chosen skills into DeepSeek Harness (DSH) sessions: each prompt or once at session start, with a settings page and a composer indicator.

Stars
0
Language
TypeScript
Created
Sep 6, 2026
Updated
Sep 6, 2026
GitHub repo

Introduction

dsh-skill-injector · DSH 技能自动注入插件

🪡 在 DeepSeek Harness (DSH) 会话中自动注入所选技能——每轮提示注入,或仅在会话开始时注入一次。 设置页 + 输入区指示条,即点即存,重启保留。

dsh-plugin license tests

English | 简体中文(本文档)


✨ 它解决什么问题

DSH 的技能(~/.agents/skills/ 下的 SKILL.md)平时是惰性的——只有你手动 /ponytail 或模型自己调用时才加载。如果你希望某个技能常驻生效(比如 ponytail 的极简风格、i-have-adhd 的输出结构),就得每轮手动敲一遍。

这个插件让你勾选一次,永久生效

设置页勾选 ponytail + i-have-adhd
        │ 即时写入 settings 传输层(无保存按钮,点下即存盘)
宿主半块
        ├─ each-prompt 模式:技能正文进系统提示,每次请求重新渲染
        └─ start-only 模式:会话开始时盖一条持久消息(按会话日志去重,绝不重复)
        │
浏览器半块
        ├─ 设置 → 技能注入:勾选列表 + 注入方式单选 + 缺失技能提示
        └─ 输入框下方指示条:技能:ponytail, i-have-adhd · 每轮(5s 刷新)

📋 功能

功能说明
⚙️ 设置页设置 → 技能注入:技能勾选列表(带描述)、注入方式单选、缺失技能提示
🪧 输入区指示条聊天输入框下方一行,实时显示当前生效的技能与模式
🔁 两种注入模式each-prompt(系统提示 section,每轮重渲染)/ start-only(会话开始盖戳一次)
📚 活注册表技能正文从 ctx.skills 实时读取,不拷贝文件——改技能立即生效,删技能优雅降级
🧩 子代理一致注入同样作用于 subagent,全 agent 树语气统一
🌏 中英双语设置页与指示条跟随界面语言(zh/en)
♨️ 重启保留真实 profile 插件:装一次,每次 DSH 启动自动加载

✅ 优点(以及为什么)

  • 零污染注入start-only 用官方 skill-invocation 消息来源盖戳,转写界面能正确标识"这是注入的技能上下文",且按会话日志去重——resume 旧会话不会重复注入。
  • 活注册表,无副本:技能文件改动立即反映到下一次请求;文件被删只列为"缺失",其余技能不受影响,恢复即自动回来。
  • 配置走官方 settings 传输层:即点即存、revision fence 防并发写坏、与其他设置同源持久化(~/.dsh/settings.yaml)。
  • API 全部对照源码验证:针对 DSH 0.1.3 逐个核实(settings owner scope、skills 带 cwd+scope 查找、agent.inject 消息形状、agent/session-start 载荷)——不是照抄可能过时的教程。
  • 宿主半块零 @deepseek-ai 运行时依赖:只依赖 schemastery;官方逻辑(renderSkillContent 等)内联复刻且字节级同形。npm 发布版与源码版的 API 漂移不会弄坏它。
  • 端到端实测通过:typecheck ✓ · 8/8 单测 ✓ · 构建产物 ✓ · HTTP 快照路由返回真实技能目录 ✓。

⚠️ 缺点与限制(读清楚再装)

  • 兼容范围窄:只在 DSH 0.1.3-alpha.1(源码版) 上验证过。DSH 是 developer preview,API 随时可能变;升级 DSH 后若设置页/注入失灵,回来查 release notes。
  • token 成本是线性的:选中的技能正文每轮请求都会发送(系统提示或首条消息)。选 3 个大技能 = 每轮多几千 token,没有缓存优化。只勾真正想常驻的。
  • start-only 不追溯旧会话:切换模式或改勾选后,已开着的会话不会补盖戳——只对之后新开的会话生效(设计如此:按日志去重)。
  • 技能列表依赖会话目录:设置页的"可用技能"来自当前会话的技能目录;空白会话(hero 阶段)可能只看到全局层技能,进入会话后才是完整的。
  • 无每技能开关粒度:只有全局"每轮 / 仅开始"一个模式,不能给不同技能配不同模式(想要?提 issue)。
  • 手动安装稍繁琐:profile 启用 pnpm 供应链策略(minimumReleaseAge)时 dsh plugin add 会被 lockfile 校验拦住,需走 README 里的手动三步(一次性,2 分钟)。
  • 无遥测/自动更新:装了就是装了,DSH 升级后需要你自己回来检查兼容性。

🔧 兼容性

环境状态
DSH 0.1.3-alpha.1(源码 checkout 运行)✅ 实测通过
DSH 0.1.2-rc.x(npm 发布版)⚠️ 未验证,客户端类型来自 rc.1 但注入逻辑未在此版本跑过
DSH Desktop⚠️ 理论兼容(普通插件不依赖桌面专属 service),未实测

🚀 安装

方式一是纯 GitHub 直装——lib/ 构建产物已提交进仓库,且带 git 安装安全的 prepare 脚本(构建失败时自动回退到已提交的产物,绝不阻断安装)。

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

dsh plugin --profile web add github:countossbot/dsh-skill-injector

pnpm ≥10 第一次会拒绝运行 git 依赖的构建脚本,安装可能失败并提示授权。在 profile 目录的 pnpm-workspace.yaml 加:

allowBuilds:
  dsh-skill-injector: true

然后重新执行上面的 add 命令。(不授权也不影响使用——prepare 会检测到无法构建,直接采用仓库里已提交的 lib/ 产物。)

安全建议:锁定 commit,让后续推送无法悄悄改变实际运行的代码:

dsh plugin --profile web add github:countossbot/dsh-skill-injector#<commit-sha>

方式 B:dsh plugin add 本地路径(先 clone 再装)

git clone https://github.com/countossbot/dsh-skill-injector.git
cd dsh-skill-injector && npm install   # prepare 自动构建;或 npm run build
dsh plugin --profile web add /path/to/dsh-skill-injector
dsh --profile web --dump-config | grep skill-injector   # 出现插件行即成功

方式 C:手动挂载(dsh plugin add 被供应链策略拦截时)

profile 启用了 pnpm minimumReleaseAgedsh plugin add 会被 lockfile 校验拦截(任何当天发布的第三方包都触发,与本插件无关)。手动三步:

# 1. 编辑 ~/.dsh/profiles/web/package.json:
#    dependencies 加  "dsh-skill-injector": "link:/path/to/dsh-skill-injector"
#    dsh.profile.bundles 数组追加 "dsh-skill-injector"

# 2. profile 目录安装
cd ~/.dsh/profiles/web && pnpm install --prefer-offline --config.minimumReleaseAge=0

# 3. 重启 DSH 宿主进程

装好后:重启 DSH → 设置 → 技能注入 → 勾选技能 → 开新会话生效。

验证安装

# 路由探针(宿主半块活体证据)
curl -s http://127.0.0.1:3080/skill-injector/api | python3 -m json.tool
# → {"ok":true,"mode":"each-prompt","selected":[...],"available":[...真实技能...],"missing":[]}

# 持久化探针(设置页勾选后)
grep -A5 skill-injector ~/.dsh/settings.yaml

⚙️ 配置

无配置文件。全部在设置页操作,存于 skill-injector settings 命名空间:

默认说明
modeeach-prompteach-prompt(系统提示,每轮)/ start-only(仅会话开始)
selected[]kebab-case 技能名,最多 16 个,自动去重

FAQ

  • 为什么没有保存按钮? 设计如此——每次点击即时写入 settings 传输层(与官方设置页同一机制),点下即持久化。
  • 改配置后对已开会话生效吗? each-prompt 下一次请求即生效;start-only 只对新会话生效。
  • 技能文件被删? 自动剔除注入并列为缺失;恢复文件后自动回来。
  • token 成本怎么算? 选中的技能正文每轮都发。一个 2KB 的技能 ≈ 每轮多 ~600 token。

🔒 安全

  • 对技能注册表只读:不写、不改名、不删除技能文件。
  • 注入内容是本地受信 markdown;不访问网络、无遥测。
  • each-prompt 路径对技能正文做 {{ 转义,避免严格插值抛错;start-only 消息保留原文。

🧱 架构

dsh-skill-injector/
├── src/
│   ├── index.ts            # 宿主半块:settings 命名空间、技能缓存、注入逻辑、HTTP 路由
│   ├── helpers.ts          # 纯函数(零 dsh import):校验/转义/渲染 → node:test 可直接测
│   └── client/
│       ├── index.tsx       # 浏览器半块:settings.section + composer.dock 两个 slot
│       └── locales.ts      # zh/en 字典
├── scripts/build.mjs       # esbuild 双产物:node ESM + client CJS 闭包工厂
├── scripts/prepare.mjs     # git 安装安全钩子:构建失败时回退到已提交的 lib/
├── tests/helpers.test.mjs  # node:test 单测
├── cordis.patch.yml        # dsh.bundle patch
└── package.json            # dsh.bundle + dsh.client 声明
数据流细节(点开)
浏览器半块 (lib/client.js, ModuleLoader 闭包工厂)
  ├─ settings.section 插槽 → 设置页
  │    读/写走 settingsScope 镜像 = settings 传输层(响应式、revision fence)
  └─ conversation.composer.dock 插槽 → 指示条
       5s 轮询 GET /skill-injector/api,失败降级显示

宿主半块 (lib/index.js, Host 进程)
  ├─ settings 命名空间 "skill-injector" (mode + selected)
  ├─ ctx.skills.get(name, {cwd: agent.session.header.cwd, scope: agent})
  │    ↑ 必须带 agent 的 cwd+scope,否则只见全局层
  ├─ each-prompt: systemPrompt.section(每次组装重渲染,{{ 转义)
  ├─ start-only: agent/session-start 时 agent.inject()
  │    source={kind:'skill-invocation',name,form:'instructions'};按 snapshotEvents() 去重
  └─ webServer 路由 GET /skill-injector/api → 只读 JSON 快照

🛠️ 开发

npm install
npm run build        # 构建 lib/
npm run watch        # 监视重建
npm test             # 构建 + 单测
npm run typecheck    # tsc --noEmit

客户端产物形状与官方 tsdown.client.ts 一致(window.__ModuleLoader__.load({id, factory})),外部依赖按 dsh.client.inject 声明从浏览器模块表解析。

🙏 致谢

与蓝本的主要差异

蓝本本插件
运行时依赖@deepseek-ai/dsh-skill/dsh-llm npm 包零(内联复刻,字节级同形输出)
设置写入自建 PUT /api/config 路由官方 settingsScope 镜像(revision fence、响应式)
API 依据可能过时的文档/类型对照 0.1.3 源码逐个验证

📄 许可

MIT