npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-bot-gateway

v0.3.9-beta

Published

DSH Bot Gateway:把 QQ(NapCat OneBot v11 / 官方机器人)/Telegram/飞书/钉钉 接成 DSH 的远程任务网关 —— 聊天里发消息即可建任务/续聊/查进度/收交付物(Cordis 宿主插件,零运行时依赖)

Readme

DSH Bot Gateway — 把聊天软件变成 DSH 的远程入口

版本:0.3.0-beta(更新记录见 CHANGELOG.md,设计契约见 SPEC.md,交接手册见 HANDOVER.md)

安装(正常 npm 渠道)

插件是标准 npm 包 dsh-bot-gateway(零运行时依赖,Cordis 宿主插件,宿主 + 浏览器双半边一体):

# 方式 A(官方 channels,推荐):装进 DSH profile 后重启 DSH
dsh plugin --profile <profile名> add dsh-bot-gateway

# 方式 B(从本地 tgz 安装,发布前验证用):
dsh plugin --profile <profile名> add ./dsh-bot-gateway-<版本>.tgz

# 方式 C(手工,任意 DSH 版本):装进 profile 的 node_modules 后重启
npm i dsh-bot-gateway        # 在 <dsh-home> 或 profiles/<name> 下执行

然后在机器级组合 <dsh-home>\cordis.patch.yml 挂载(零配置开箱即用,运行时数据默认落 $DSH_HOME/bot-gateway/;需要自定义路径才写 config):

- insert:
    - id: bot-gateway
      name: dsh-bot-gateway
      # config: { tasksRoot, statePath, settingsPath }  可选,默认 dsh-home/bot-gateway/

版本升级:发布新版 → dsh plugin --profile <name> add dsh-bot-gateway@<新版本> → 重启 DSH。 改源码 = 改仓库发布新版(npm 标准流),不再有 junction / ?v= 热重载(见「六、改代码」)。

桌面截图监控(desktopWatch)

配置入口:看板「设置」→ desktopWatch(持久化在 settings.json,保存即热生效)。

  • enabled: true 开启后,网关用 Electron desktopCapturer(非 Windows 原生截图工具) 每 intervalSec(默认 60)秒捕获全部显示器,主动推送到 onebot11 allowUsers (或 desktopWatch.pushTo 显式指定的目标)。
  • QQ 官方机器人协议不允许主动推送 —— 定时推送走 NapCat 个人号通道; QQ 官方用户可在 5 分钟被动窗口内发 /桌面 按需要一张。
  • 截图落盘在 dsh-home/bot-gateway/screen-shots/,滚动保留最近 keepLast(默认 60)张。
  • 任意通道发 /桌面(或 /desktop)立即现拍一张当前桌面发回 —— 捕获进程优先处理 按需请求,不吃上一周期的存货。
  • 锁屏处理:屏幕锁定时截的图不是锁屏 —— 捕获端自动改抓桌面应用窗口的实时画面 (取画面最大的有效窗口;文件名带 -L 标记,/桌面 回复会注明「屏幕处于锁定状态」); 系统连窗口画面都冻结时回退最后一张可用全屏帧。黑帧一律不落盘。
  • 免打扰时段(dnd: { enabled, start, end },如 23:00 → 08:00,可跨零点): 时段内不自动推送 —— 截图照拍、滚动保留照做,期间新图只存档,时段结束后也不会 积压补发(整段静默);补发队列同样冻结到时段外;/桌面 手动要图不受限。
  • 捕获依赖 electron.exe:默认自动探测 DSH 桌面工作区 (Desktop\DSH\node_modules\electron\dist\electron.exe),也可用 electronPath 显式指定, 或设环境变量 BOT_GATEWAY_ELECTRON / DSH_WORKSPACE。

把 QQ(NapCat / OneBot v11 + QQ 官方机器人)、Telegram、飞书、钉钉接入 DSH: 在手机聊天软件里发一条消息,就能创建任务、续聊、查进度、停止任务 —— 与本地任务拥有完全相同的权限与模型能力。

NapCat 一键安装 + 全部账号设置都在网页看板完成,无需改配置文件。

DSH 版本适配表

| 插件版本 | 适配 DSH 版本 | 说明 | |---|---|---| | 0.3.0-beta | 0.2.1-alpha.1(实测) | 电脑重启后 NapCat(QQ) 自动快速登录不再每次手动扫码(修复 wsl 登录轮询被守卫拦截的 bug + 启动自动 SetQuickLogin);WSL 完全无窗口启动(powershell Hidden 包裹 + 冷启动预暖,桌面不再弹终端窗口);testedDshVersion → 0.2.1-alpha.1 | | 0.2.3-beta | 0.1.7-rc.1(实测) | 兼容声明更新:host 服务依赖与浏览器半边契约逐项核对 0.1.7 实现一致;testedDshVersion → 0.1.7-rc.1;含 0.2.2-beta 全部能力 | | 0.2.2-beta | 0.1.7-rc.1(实测) | 新增 /pair 手机配对命令(全局管理员私聊获取配对二维码;依赖 DSH 未来发布的 mobileCompanion 服务,未发布前友好提示) | | 0.2.1-beta | 0.1.2-rc.1(实测) | 设置页面 UI 与 DSH 主题对齐(继承 --dsw-* 设计令牌,换肤实时跟随) | | 0.2.0-beta | 0.1.2-rc.1(实测) | npm 标准包重构(main=宿主入口、exports["./client"]、单裸包名行挂载,无 junction/?v=);含 0.1.0-beta 全部能力:桌面截图监控(现拍 + 锁屏处理)/ 免打扰时段 / 多媒体承载 / AGENTS.md 规则手册 / QFace 表情真值 / 联络官派发 | | 0.1.0-beta | 0.1.2-rc.1(实测) | 桌面截图监控 / 多媒体承载 / AGENTS.md 规则手册 / QFace 表情真值 / 联络官派发(file:// /v= 挂载时代) | | 0.0.6-beta ~ 0.0.7-beta | 0.1.2-alpha.4(实测) | 浏览器半边适配 0.1.2 的按包名注册机制(工厂 id dsh-bot-gateway);宿主半边兼容 0.1.1-rc.2 | | 0.0.1-beta ~ 0.0.5-beta | 0.1.1-rc.2(实测) | 发布时仅存在该 DSH 版本;装在 0.1.2 上宿主半边可用,但 GUI 设置分区不会出现(client 工厂 id 与 0.1.2 花名册行 id 不匹配) |

  • 适配范围由 package.json 的 dsh.compat = { minDshVersion, testedDshVersion } 声明。
  • 查看当前 DSH 版本:dsh --version 或 GUI「设置 → 关于」。
  • 自检浏览器半边注册状态(0.1.2+ 的 Web 鉴权使外部探测失效,用插件自证端点): curl http://127.0.0.1:<后端端口>/bot-gateway/api/client → registered: true 即正常。

入口已固化进 GUI:DSH 网页界面「设置 ⚙」面板 →「机器人网关」分区 (「通用」与「模型」之间),内嵌完整看板 —— 无需记忆 URL,后端端口漂移自动跟随。 备用直达:http://127.0.0.1:<后端端口>/bot-gateway/。

项目特性:零 npm 依赖(全部协议手写,仅用 node: 内建与全局 API); npm 标准包(Cordis 宿主插件,main 即宿主入口,单裸包名行 = 宿主 + 浏览器双半边); 13 组离线单测 + jsQR 解码回环验证。

┌─────────────┐   OneBot v11 WS    ┌──────────────────────────────────┐
│  NapCat/QQ  │◄──────────────────►│  bot-gateway (DSH 宿主插件)      │
│  Telegram   │   TG Long Poll     │   ├─ 命令路由 /new /status /stop │
│  飞书       │   飞书长连接 WS     │   ├─ TaskManager + state.json   │
│  钉钉       │   钉钉 Stream WS   │   └─ agents.create + preset 挂载 │
└─────────────┘                    └──────────────┬───────────────────┘
        ▲                                          │ followup / whenIdle
        │ NapCat WSL 发行版(官方镜像,            ▼
        │ 自带完整 Linux QQ,插件一键安装托管)  DSH Agent(工具齐全、会话持久化、
                                                  独立工作目录,权限继承宿主)
  • 源码仓库:C:\Users\lcl\Desktop\DSH插件开发\DSH Bot\(git,发布源;npm 包从它构建)
  • 控制台(主入口):DSH GUI「设置 ⚙」→「机器人网关」分区(推荐,端口无关); 备用直达:http://127.0.0.1:<后端端口>/bot-gateway/ —— 每个平台一个独立设置页: 📊 总览(平台状态 + 任务列表)|🐱 QQ 个人号(NapCat 安装/扫码/OneBot11)|🤖 QQ 官方机器人|✈️ Telegram|🐦 飞书|💬 钉钉|⚙️ 通用设置(模型/任务参数)

一、支持的平台

| 平台 | 协议 | 模式 | 扫码 | |---|---|---|---| | QQ(NapCat) | OneBot v11 | 正向 WS(我们连 NapCat)/ 反向 WS(NapCat 连我们) | ✅ 看板扫码中继 | | QQ 官方机器人 | QQ Bot WebSocket | 官方 wss 网关 + 被动回复 | —(后台配置) | | Telegram | Bot API | 长轮询 getUpdates | —(@BotFather 建 bot) | | 飞书 | 长连接 | 官方 callback/ws(protobuf 帧) | —(开放平台配置) | | 钉钉 | Stream Mode | 官方 gateway/connections/open | —(开发者后台配置) |


二、快速开始(QQ · 全程网页操作)

0. 前置:无(WSL2 为 Windows 内置组件)

NapCat 部署默认采用 wsl 模式:插件把官方 mlikiowa/napcat-docker 镜像(自带完整 Linux QQ 与 NapCat)导入为 Windows 内置的 WSL2 发行版并全程托管 —— 无需安装 Docker Desktop 或任何 第三方软件。

  • 本机已有 Docker 镜像:安装时直接 docker export 复用,零下载(约 40 秒完成迁移)
  • 本机没有 Docker:插件经 Alpine 构建器从 Docker Hub 直拉镜像层并在本地合并成发行版
  • 前置条件仅有 WSL2(Win10/11 内置;若未启用:管理员 PowerShell 运行 wsl --install 并重启)

备选 docker 模式:本机已装 Docker Desktop 时可切换(安装 = docker pull,崩溃自动重启)。 历史说明:曾尝试 NapCat.Shell.Windows.Node.zip(自包含 node.exe + QQNT 核心), 但上游 v4.18.19 该包缺少 wrapper.node 依赖的 crypto.dll/ssl.dll(这两个文件只在 QQ 官方安装包内,且腾讯 CDN 对该包做了地域封锁),本机无法补齐 —— 已弃用。

1. 一键安装 NapCat(网页)

  1. 打开 http://127.0.0.1:53035/bot-gateway/
  2. 在「🐱 NapCatQQ 进程托管中心」卡片点击 🚀 一键安装 NapCat (WSL2 内置运行,免 Docker)
  3. 等待进度条走完(首次约 1.5GB 下载;本机有 Docker 镜像则秒装),发行版自动启动

插件自动完成:获取镜像 rootfs → wsl --import 导入发行版 → 生成 webui.json(随机 token)

  • onebot11.json(WS 服务器 3001)并同步进发行版 → 启动常驻托管进程(entrypoint.sh → Xvfb 虚拟屏 → Linux QQ)。端口经 WSL2 localhost 转发暴露 3001(OneBot WS)与 6099(WebUI), 适配器无感知。从 docker 模式切换过来时,旧容器会自动停止释放端口。

2. 扫码登录

  1. 看板「扫码登录」卡片显示实时二维码(插件把 NapCat 返回的 txz.qq.com 登录链接 本地渲染为 QR 图片 —— 该链接是给手机 QQ 扫的,浏览器打开只是说明页)
  2. 手机 QQ 扫码 → 卡片变绿即登录成功(登录态持久化在发行版 VHD,重启后可「快速登录」免扫码)

3. 设置允许的 QQ 号(安全闸门!)

  1. 切换到「🐱 QQ 个人号」页(顶部导航切换;URL hash 自动记忆,如 #/napcat)
  2. 「允许用户 (allowUsers)」填你自己的 QQ 号(每行或逗号分隔)
  3. 点 💾 保存 QQ 个人号设置 —— 立即热生效,无需重启

不知道自己的 QQ 号?先随便发条消息给机器人,未授权回复会把你的用户标识原样告诉你, 再回来填上。allowUsers 留空 = 拒绝所有人。

4. 发消息试一试

手机 QQ 私聊机器人(或群里 @机器人):

/new 帮我在桌面上创建一个 notes.txt,内容写"远程任务测试"

几秒后机器人回复「▶️ [xxxx] 开始执行…」,任务完成后回报结果。

任务模型默认 agentrouter/glm-5.3,可在设置页「任务模型」里改。


二·五、用户隔离 · 人格 · 自进化(0.1.0-beta)

每个与机器人发起会话的用户自动获得一个专用文件夹(<dsh-home>\bot-gateway\users\<来源-账号>\), 内含多层记忆(容量有上限,由后台记忆整理子代理自动瘦身治理,成年累月不膨胀):

| 要素 | 路径 | 作用 | |---|---|---| | 自进化档案 | PROFILE.md | 机器人对该用户的长期认知(≤4KB,偏好/习惯/重要信息),每轮先读、持续自我更新;看板可直接编辑 | | 情感记忆 | soul/soul.md + soul/moments.md | 关系基调/里程碑/相处备忘 + 重要时刻(≤120 行,超限自动蒸馏) | | 对话日志 | data/logbook.md | 按日期的往期对话摘要(会话轮换封卷时写入)——「我们那天聊了什么」的回忆入口 | | 关注事项 | data/focus.md | 用户某段时间特别关注的事(考试/求职/项目/健康),带热度与跟进建议;机器人主动跟进进展,不需要用户反复叮嘱,超 30 天未动自动归档 | | 媒体库 | data/media/ + index.jsonl | 用户发来的图片/文档/语音/视频按月分区落盘 + 追加式索引;机器人用 read_image 看图、grep 索引找「那张图」 | | 数据库 | data/ 其余 | 该用户的结构化数据:游戏进度、记账流水、心情日记、积分榜 | | 技能包 | skills/ | 剧本/玩法/检查单等 .md 技能说明,机器人按需读取,也可为用户定制新技能包写入 |

联络官模式(默认开,看板可关):主会话是常驻对话伙伴 —— 闲聊直接聊、有温度; 复杂任务派子代理执行、自己盯进度汇报,不会干活干到不理人。每轮先揣摩你当下的状态 (忙不忙、心情如何、在等什么),再决定怎么回;你交代的关注事项它会自己记着、自己追。 任务跑着你插话,它会当场判断:是改主意(马上调方向)、是新任务(派出去不打断手头的)、 还是就聊两句(顺嘴接住)。

说话方式:像朋友在 QQ 上打字那样回你 —— 短句、口语、有态度;没有列表腔、 客服腔、作文腔,也不拿状态小图标装点门面。

文件权限硬限制:除「全局管理员」外的所有人格,会话都运行在 DSH 原生 workspace-write 沙箱下 —— 可写根 = 会话工作目录 = 该用户的专用文件夹,读写越界即被拒; --cwd / /cwd 对受限人格自动拒绝。远程用户无需也无法响应审批弹窗 (会话审批策略固定 never)。

六种人格(看板「👥 用户」页下拉即切,下一条消息生效;新用户默认人格可在 「⚙️ 通用设置」里配置):

| 人格 | 沙箱 | 定位 | |---|---|---| | 🛠️ 全能助手(默认) | 锁定用户文件夹 | 完整任务执行,只是被限制在自己的文件夹内 | | 🎭 剧本杀主持人 | 锁定用户文件夹 | 沉浸式 DM:发线索、演 NPC、推进章节、复盘;进度存 data/,剧本放 skills/ | | 🎮 小游戏 | 锁定用户文件夹 | 猜谜/接龙/21点/文字冒险,带 data/scores.md 积分榜 | | 💌 伴侣 | 锁定用户文件夹 | 倾听共情、记重要日子与偏好(写入 PROFILE.md 与 data/) | | 📅 生活助手 | 锁定用户文件夹 | 日程提醒、记账、菜谱、习惯打卡;越用越懂你 | | 👑 全局管理员 | 无沙箱 | 受信用户(如你自己的 QQ):可 /cwd 指定任意工作目录,慎用 |

管理操作(看板「👥 用户」页):

  • 人格切换:即时写入档案,下一条消息生效;已运行的会话即时收到新沙箱策略
  • 封禁/恢复:封禁后该用户消息被直接拒绝
  • 档案编辑:直接查看/修改 PROFILE.md(与机器人自进化写入的是同一份文件)
  • 重置工作区:解除粘性会话绑定,下一条消息按当前人格重新建档建会话(原记录保留)

三、其他平台配置(每平台一个独立设置页)

QQ 官方机器人(q.qq.com 注册)

「🤖 QQ 官方机器人」页填 appId + clientSecret,勾选启用,保存即连。页面顶部的扫码绑定卡片 自动从官方 API 拉取机器人信息(名称/头像)并本地生成添加到群二维码 —— 手机 QQ 扫码即可把机器人 加进你的群(无需手动复制链接)。官方机器人要求被动回复(收到消息 5 分钟内、最多 5 条),网关已自动 处理 msg_seq 递增。群里使用需要开启「机器人可以被@」。未上架的机器人可在控制台沙箱配置添加测试人员。

Telegram

@BotFather 创建 bot 拿 token;allowUsers 填你的数字 user id(给 @userinfobot 发消息可查)。 大陆网络可设 apiBase 指向自建反代。

飞书(open.feishu.cn 创建企业自建应用)

开放平台 → 事件与回调 → 选择「使用长连接接收事件」,订阅 im.message.receive_v1, 权限开 im:message、im:message:send_as_bot。

钉钉(open-dev.dingtalk.com 创建应用 + 机器人)

开发者后台 → 机器人配置 → 消息接收模式选 Stream 模式,无需公网 IP。

设置存储与生效

所有网页设置持久化在 <dsh-home>\bot-gateway\settings.json(原子写盘),每页独立保存 (服务端深合并部分配置,互不影响其他平台),保存即触发 reconfigure 热生效: 旧适配器卸载 → 新配置装配,NapCat 进程/容器不受影响。cordis.patch.yml 里只剩安装路径类配置,无需再改。


四、命令参考

| 命令 | 说明 | |---|---| | /new <描述> [--cwd <绝对路径>] | 创建新任务(同账号沿用同一持久会话;--cwd 仅该账号首个任务生效) | | /status [taskId] | 查看任务实时状态(正在调什么工具、第几轮等) | | /list | 列出本聊天最近 10 个任务 | | /stop [taskId] | 停止运行中的任务(仅当前活跃任务会真正取消执行中的轮次) | | /switch <taskId> | 切换本聊天的活跃任务 | | /cwd <绝对路径 \| reset> | 设置 / 重置本聊天的默认工作目录(账号绑定会话前有效) | | /help | 命令帮助 | | (直接发文本) | 无活跃任务时自动当新任务;任务运行中会当场判断你是改主意、加新活还是想聊两句,分别处理 |

任务运行时每 3 分钟自动推送一条进度(设置页可调)。

工作目录规则(默认): <dsh-home>\bot-gateway\tasks\<日期>-<任务id>-<标题slug>\,互不污染; 用 --cwd 或 /cwd 可显式指定任意目录。

账号粘性会话(0.0.5-beta 起):

  • 每个远程账号(一个群或一个私聊用户)固定一个持久 DSH 会话:该账号的 所有消息、所有任务(含 /new)都进同一会话,跨 DSH 重启自动 resume 续用;
  • 会话在 DSH 侧边栏的标题被钉住为 来源-用户类型-账号-远程会话 (如 QQ-群组-88888-远程会话、QQ-用户-10001-远程会话),LLM 自动 命名被永久压制,一眼可辨来源;
  • 工作区随会话一起粘住(DSH 会话与 cwd 绑定不可更换):该账号首个任务确立 工作目录后,后续 --cwd / /cwd 不再更换(会提示已绑定);
  • 若会话被手动删除(文件进了 session-cleaner 回收站),下一条消息会自动 换新会话自愈,任务不中断。

五、安全须知(务必阅读)

  1. 远程任务继承宿主全部权限。当前宿主是 danger-full-access(完整读写、任意命令), 远程任务同样拥有。allowUsers 是唯一闸门 —— 只加自己的账号。
  2. 群聊默认需要 @机器人 才响应(groupTrigger: mention),且可再加 allowGroups 白名单限定群号。
  3. 状态看板只监听本机回环(127.0.0.1),并有 Host/CSRF 校验,外网访问不到。
  4. NapCat 容器端口(3001/6099)只映射到 127.0.0.1,容器内配置强制 0.0.0.0 仅服务于端口映射。
  5. state.json(任务注册表)与任务工作区都在 dsh-home\bot-gateway\ 下,删除该目录即清空所有远程任务痕迹。

六、改代码 & 版本升级

改运行配置(推荐方式):看板设置页保存即 reconfigure 热生效,或改 cordis.patch.yml 里本条的 config 保存即热重载 —— 两者都无需动版本号。

改源码 / 版本升级:插件已是 npm 标准包,采用标准发布流,不再有 ?v= 缓存链:

# 1. 改源码(git 仓库),跑测试
npm test
# 2. 发布新版本(package.json version + index.mjs PLUGIN_VERSION 同步)
npm pack            # 本地 tgz 验证(files 白名单,见 package.json)
npm publish         # 需要 npm 登录(npm adduser / token)
# 3. 目标机安装新版本后重启 DSH
dsh plugin --profile <name> add dsh-bot-gateway

为什么没有热重载了:ESM 缓存按 URL 键控,?v= 机制曾在 file:// 开发态下绕过缓存; npm 包的标准做法是「安装新版本 → 重启」(DSH 冷启动必读最新代码,无缓存问题)。 本机当初的 junction 开发挂载已退役,源码目录只作为发布源使用。

诊断利器:<dsh-home>\bot-gateway\debug.log 记录 agent 挂载、每轮事件数、被循环吞掉的 agent/error——排查"任务没反应"先看它。


七、架构与扩展性

7.0 项目与版本管理

  • 产品版本:package.json version 与 index.mjs 的 PLUGIN_VERSION(发布时同步)—— 看板徽标 / /api/status / 启动日志展示;变更记录在 CHANGELOG.md
  • 测试:npm test 跑全部 13 组离线套件(脚本清单见 package.json)
  • 入库范围:源码 + 文档 + 测试;runtime-data/(含 token 的运行时状态)与 test/jsQR.cjs(第三方测试依赖)已由 .gitignore 排除
  • 发布范围:package.json files 白名单(宿主入口 + client + lib/ + 文档), 测试与探针不随包发布

7.1 双半边架构(宿主 + 浏览器)

插件由组合树的一行组成(在 <dsh-home>\cordis.patch.yml 机器级补丁层 —— 注意不是 profiles\web\cordis.patch.yml:DSH Desktop 桌面壳在后端启动失败时会把 整个 profiles 目录隔离为 profiles.broken-<时间戳> 并重建,profile 级补丁会随之丢失; 机器级补丁不受影响,重启后始终生效):

| 行 | name | 作用 | |---|---|---| | bot-gateway | dsh-bot-gateway(裸包名) | 一行两半边:宿主 = 包 main(index.mjs,全部适配器/NapCat 托管/看板路由);浏览器 = client-modules 按名扫描 package.json 的 dsh.client 声明,经 exports["./client"] 把 client.js 纳入花名册 |

浏览器半边注册机制(0.1.2+):

  • client-modules 从 Loader 条目定位 package.json(裸包名行直指 <dsh-home>\node_modules\dsh-bot-gateway\package.json),按清单名 dsh-bot-gateway 注册浏览器半边 —— 无需单独的 client 行 (旧 0.1.1 时代需要 client-entry.mjs 空占位 + 第二行,已随 npm 化废弃);

  • client.js 的工厂注册 id 与 slots.register 分区 id 必须是 dsh-bot-gateway(= 包清单 name):0.1.2 的 arrive() 严格要求 工厂注册 id === 花名册行 id,不匹配时设置分区静默缺失;

  • 分发 URL 为组合 URL(/plugins/??<id>/client.js&rev=<rev>,rev 为不透明分配值)—— 对插件透明,外部无法靠探测 URL 验证注册,用 /bot-gateway/api/client 自证(见上文适配表)。

  • client.js(浏览器 bundle):经典脚本 + __ModuleLoader__.load CJS 工厂, require("react") / slots 服务取自 shell 静态种子表;向 settings.section 插槽注册「机器人网关」分区(order=5),内容为同源 iframe 内嵌 /bot-gateway/

  • 解析路径:<dsh-home>\node_modules\dsh-bot-gateway\(npm 标准包布局; profiles\<name>\node_modules 可放 junction 镜像保证 profile 解析稳定)

  • 启动自检日志:每次挂载/卸载/挂路由写入 <dsh-home>\bot-gateway\boot.log (后端 stderr 对桌面用户不可见;启动后若看板 404,先看这个文件定位)

在新机器上安装(见文首「安装(正常 npm 渠道)」):dsh plugin --profile <name> add dsh-bot-gateway(或 npm i dsh-bot-gateway 装进 profile 的 node_modules),再在机器级 patch 加裸包名行,重启 DSH 生效。

启动可靠性(0.0.3-beta 关键修复):看板路由用 ctx.inject(['webServer'], …) 子纤维注册 —— webServer 是异步就绪的服务(listen + webStartup 依赖链),启动竞态下 可能晚于本插件 apply;旧实现一次性 ctx.get 会永远错过并静默禁用看板(表现为 重启后 /bot-gateway/ 404 空白页、设置分区 iframe 空白)。子纤维保证服务出现即挂载。

7.2 文件布局

index.mjs              插件入口(宿主半边):DEFAULTS 合并(patch.yml ← settings.json 双层)、
                       reconfigure 热重配、NapCat 管理器装配、看板路由注册
client.js              浏览器半边 bundle:注册 DSH GUI「设置」面板的「机器人网关」
                       分区(settings.section 插槽,同源 iframe 内嵌看板)
client-entry.mjs       裸包名行的空操作宿主占位(见 7.1 双半边架构)
package.json           项目元信息 + 测试脚本(零 npm 依赖,type: module,
                       含 main/exports/dsh.client 客户端声明)
CHANGELOG.md / SPEC.md 更新日志 / 设计规格(实现契约)
.gitignore             排除运行时状态与第三方测试依赖
lib/core.js            Gateway:TaskManager、命令路由、runTurn 驱动、
                       session/event 进度通知、state.json 持久化与重启恢复
lib/util.js            日志、退避重连、消息分块、makeUserMessage、RFC6455 WS 服务器
lib/settings.js        SettingsStore:settings.json 原子读写(tmp+rename)与深合并
lib/napcat-process.js  NapCat 一键安装与托管:wsl 模式(镜像 rootfs → WSL2 发行版,
                       docker export 快路径 / Docker Hub 直拉慢路径,常驻 wsl.exe 托管)
                       + docker 模式(pull/run/start/stop)+ windows 模式(实验性)
lib/napcat.js          NapCat WebAPI 客户端(扫码中继;自动兼容新旧两代鉴权:
                       旧版 {token} 明文 / 新版 {hash: sha256(token+".napcat")})
lib/webui.js           WebUI 服务端:路由挂载(HTML 外壳 + app.js + 12 个 API),
                       三层安全校验:回环 + Host端口 + CSRF;QQ 官方机器人信息/
                       绑定二维码代理(60s 缓存)
lib/qrcode.js          自包含 QR Code 生成器(无第三方依赖):GF(256) Reed-Solomon、
                       掩码惩罚评分自动选优、PNG 编码(Node 内置 zlib);
                       V1-V6 / EC-M,最长 106 字节
lib/webui-app.js       前端应用(独立脚本文件):每平台独立设置页 + hash 路由 +
                       分视图部分保存(深合并);独立文件规避模板字符串嵌套转义问题
lib/pb.js              飞书 pbbp2.Frame protobuf 编解码
lib/adapters/*.js      5 个平台适配器,统一工厂签名:
                       createAdapter(kind, adapterConfig, deps) →
                         { kind, start(), stop(), status(), sendText(chatTarget, text) }

加新平台只需三步:

  1. 新建 lib/adapters/<platform>.js,实现 createAdapter 工厂签名(收消息 → 调 deps.core.onMessage({ adapter, chatId, userId, text, isGroup, reply }), reply 是回发函数;发送 → 实现 sendText)
  2. 在 index.mjs 的 DEFAULTS.adapters 加默认配置 + 装配注册 + 设置页加表单
  3. bump 版本号(见上节)

DSH 侧接入要点(对齐 dsh-host-apiproxy 的 ensureSession 模式): agents.get(sessionId) 活跃复用 → 持久化命中走 agents.resume → 全新会话走 agents.create(绝不能先 sessions.create 再 agents.create,会撞 "already exists")。 创建时必须传 setup: (agentCtx) => presets.mount(agentCtx, presetId) 挂载工具集, 否则模型没有任何工具、只会空谈;setup 返回值必须是 undefined。


八、测试

cd <bot-gateway 源码目录>
npm test                    # 或逐个执行:
node test\smoke.mjs          # 冒烟:工具函数、配置合并、命令解析
node test\settings-test.mjs  # SettingsStore 深合并/原子写盘、NapCat 配置生成(docker+windows)、reconfigure 流程
node test\ws-server-test.mjs # RFC6455 WS 服务器(分片/ping/close)
node test\adapter-test.mjs   # 5 适配器协议与事件链
node test\stagec-test.mjs    # protobuf 编解码 + 飞书/钉钉适配器
node test\qrcode-test.mjs    # QR 生成器结构自检(定位/时序/暗模块/比例)
node test\media-test.mjs          # 媒体入库:分区落盘/JSONL 索引/去重/限额/检索/消毒
node test\qrcode-decode-test.mjs # QR 生成↔jsQR 解码回环(含 UTF-8 中文)
node test\image-outbound-test.mjs # 图片出站:提取/安全校验/路径脱敏/降级
node test\wsl-slowpath-test.mjs # WSL 慢路径端到端:Alpine 构建器直拉 Docker Hub 镜像(需 WSL2)
# 端到端(需 DSH Desktop 运行中;起 Mock NapCat 推 /new 任务并断言完成回复):
node test\mock-onebot-server.mjs --expect-v=<当前V> --port=3999 --wait-ms=300000

第三方测试依赖:qrcode-decode-test 依赖 jsQR 1.4.0(MIT)作为解码预言机, 该文件不随仓库分发(.gitignore 已排除),首次运行前获取:

curl.exe -sL -o test\jsQR.cjs https://cdn.jsdelivr.net/npm/[email protected]/dist/jsQR.js

缺失时该测试自动跳过(退出码 0),不影响其余套件。

e2e 用独立端口(如 3999)避开真实 NapCat 容器占用的 3001;测试前先通过看板设置页把 OneBot11 url 临时切到 ws://127.0.0.1:3999(顺手实测 reconfigure 热切换),测完切回。

测试辅助工具:test\inspect-session.mjs <关键词>(查任务会话)、 test\zcat-session.mjs <journal.zstd>(多帧 zstd 解压会话日志)、 test\ws-probe.mjs <ws-url>(WS 连通性探测)、test\pe-imports.mjs <dll>(PE 导入表解析)。