dsh-kubejs: Customize Installed DSH Plugins with a Script Package

在 DeepSeek Harness(DSH)的插件生态中,修改现有插件通常意味着直接编辑其源码,这会导致版本更新后修改失效、改坏拖垮启动等风险。dsh-kubejs 引入了 KubeJS 的核心模式:将修改逻辑剥离到独立的脚本包中,通过声明式配置让脚本作用于已安装的插件,而不触碰插件源码。

核心功能

dsh-kubejs 自身是普通 DSH 插件,负责加载脚本;脚本存放在独立目录,与插件代码完全隔离。

修改者与修改分离

脚本集中放在独立目录,与插件代码完全隔离,插件更新或重装不会丢失修改。修改逻辑通过 activate(api) 导出,作用于已存在的东西。

目标插件依赖管理

脚本按目标插件分包,通过 manifest.json 声明依赖。若目标插件未安装或版本失配,整包禁用并报警,绝不静默失效。

配置覆写账本

通过 api.config.override 写入配置,所有变更记录在 cordis.patch.yml 的托管区块中,支持精确摘除。同一插件实例分多次写不同路径是累加而非覆盖。

五大 API 原语

脚本通过 activate(api) 获得五个原语:

  • api.on(event, handler):事件钩子(真实挂在宿主 cordis 事件上)。
  • api.slot(id, props, Component):向 client 槽位注册 UI 组件。
  • api.config.override(path, value):配置覆写。
  • api.service.wrap(name, wrapper):服务包装(洋葱式)。
  • api.fetch.wrap(matcher, handler):全局 fetch 拦截(洋葱式)。

管理面板与工具集

提供管理面板浏览脚本包状态、失配红标、执行状态与配置账本。同时提供四个专用工具:kubejs_inspect、kubejs_write_script、kubejs_reload、kubejs_check。

安装

在 DSH Desktop 的「插件」面板中输入以下任一地址安装:

github:YuMo-233/dsh-kubejs

或直接填仓库地址 https://github.com/YuMo-233/dsh-kubejs。官方安装器会自动完成拉包、bundles 登记、cordis.patch.yml 注册,装完重启即可。

典型用法

事件钩子

export function activate(api) {
    // 只看不动:返回 undefined 就是完全透传,绝不干扰 DSH
    api.on('agent/pre-step', (payload) => {
        api.log.debug('当前步:', payload.step);
    });

    // 改决策:一定要先 await next() 拿到宿主的内建决策,再 spread 它
    api.on('agent/pre-step', async (payload, next) => {
        const decision = await next();          // { kind: 'enter', messages: [...] }
        return { ...decision, delayHint: 800 };
    });
}

fetch 拦截

export function activate(api) {
    api.fetch.wrap({ urlIncludes: '/v1/chat/completions' }, async (request, next, helpers) => {
        // 把「整条请求一刀切超时」换成「没字节流动才超时」的看门狗
        const idle = helpers.createIdleSignal({ firstByteMs: 60_000, idleMs: 300_000, upstream: request.signal });
        request.init.signal = idle.signal;

        const res = await next();                          // 返回 undefined 则由框架代发
        return helpers.wrapResponseBody(res, idle.pulse, idle.dispose);
    });
}

热重载

kubejs_reload 即时生效(无需重启),用于修改事件钩子、配置覆写或 fetch 拦截规则。

使用注意事项

钩子与决策

  • 不拥有决策就返回 undefined(透传),别自造对象——自造会顶掉宿主的内建决策字段。
  • 想改就先 await next(),再 spread 它的返回值。
  • 钩子是异步的,handler 可以是 async;慢 handler 会拖慢事件。
  • api.ctx 全量直通(读或改场景),但想造新东西时请写成独立插件。

脚本约束

  • 脚本不能造新接入点(provide 新服务/注册新工具/新路由)。
  • client 脚本不能 import/export(只能用 require())。
  • manifest.json 不能带 BOM(会导致解析失败)。
  • 脚本必须用 ESM 导出 activate(写成 CJS 会静默失效)。
  • 标记行必须是注释,以 # 开头(写在 cordis.patch.yml 中)。

价值总结

dsh-kubejs 允许开发者在不修改插件源码的情况下,通过独立脚本包对已安装插件进行定制。这种模式解决了直接改插件导致的版本更新丢失、改坏拖垮启动以及修改散落难以审查的问题。脚本按目标插件分包,配合配置覆写账本和热重载机制,提供了安全、可回滚的修改能力。

了解更多或获取源码,请访问 GitHub 仓库。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye