Skip to content

Releases

v0.3.0 — 微信远程审批(在手机上批准危险操作)

Choose a tag to compare

@zhengjy01 zhengjy01 released this 27 Sep 14:25

微信远程审批:在手机上批准危险操作

approval 新增 wechat 模式并设为默认——微信发起的回合遇到需要批准的敏感操作时,问句会发到同一个微信对话,你在手机上回一个字就能决定:

⚠️ 需要审批
工具:bash
理由:命令超出只读范围

回复 1 = 批准一次 / 2 = 拒绝
180 秒内未回复则转到电脑上的 DSH 界面处理。
  • 回 1(也认 /approve、批准、同意、允许、通过)→ 放行这一次;回 2(也认 /reject、拒绝、不同意、驳回)→ 拒绝。随后你会收到回执「✅ 已批准一次(bash)」/「❌ 已拒绝(bash)」。
  • 审批答复会被认领,不再当成新 prompt 发给 agent(此前这是「微信侧做不了审批」的根因)。
  • 兜底一律让位 GUI,不静默失败:超过 approvalTimeoutMs(默认 180 秒)、问句发不出去(会话窗口关闭 ret=-2)、或部署里根本没有出站通道(纯 HTTP bridge)→ 一律交给电脑上的 GUI answerer,并告诉你「已转到 DSH 界面」。
  • 同一对话一次只问一条,其余排队(问句里标注「还有 N 条排队」),答完自动发下一条;回合结束 / 取消 / 超时时待批作废为 cancelled,流程不会挂死。
  • GET /health 新增 approvals 字段(当前待批数量)。

⚠️ 行为变更

  • approval 默认值由 reject 改为 wechat。 想维持旧行为:approval: reject(自动拒绝并在回复里注明)或 approval: ignore(完全留给 GUI)。
  • 要有审批请求,会话权限预设不能是 danger-full-access —— 它映射成 approval: never,ask 不会进入审批瀑布,也就不会有任何问句。请用 workspace-write 或 read-only。
  • 审批请求只带工具名 + 理由(不含命令参数),授权只有一次性(allowed-once,没有「以后都允许」);本模式只覆盖桥接回合,GUI / 派发器 worker / 任务看板跑的回合不走这条通道。

升级步骤

  1. 升级插件:dsh plugin --profile web add 'dsh-wechat-clawbot@^0.3.0'(desktop profile 把 web 换成 desktop)。
  2. 确认你的 profile 配置里 approval 是 wechat(默认即是);要回旧行为就显式写 reject 或 ignore。
  3. 重启 DSH(宿主插件改动必须重启才生效)。
  4. 把会话权限预设改成 workspace-write(或 read-only)——否则不会产生审批请求。
  5. 在微信里给机器人发一条会触发审批的指令(例如「把这个目录里的临时文件删掉」),收到问句后回 1 验证放行。

其他修复

  • 同步了可移植性门禁脚本:DSH 0.1.7 起客户端 bundle 的交付地址改为文档相对路径(plugins/??<包名>/client.js,没有前导斜杠),仓库里 scripts/portability.mjs 的旧正则要求 /plugins/?? 开头,导致门禁第 6 步对每一个带客户端半的插件都误报「客户端半没注册」。已从 release-kit 母版同步修复(可选前导斜杠 + 在全部 combo 里查找 + 下载前补绝对前缀)。

测试

  • npm test:65 项全绿(窗口分类与保鲜 18 + 会话结算 7 + 新增审批 40)。
  • 隔离 DSH_HOME 可移植性门禁 npm run verify:full:✅ 通过(tarball 安装进空 profile、宿主探针 200、客户端 bundle 进启动清单、30 秒稳定)。

📸 README 截图待补:中英 README 的「远程审批」一节已按发布说明规范留出 2 个截图位(微信里的审批问句、回复后的回执),补图后替换占位块即可(落点 docs/images/)。

v0.2.2 — 修正窗口判据(探针不作数,只认真实发送)

Choose a tag to compare

@zhengjy01 zhengjy01 released this 19 Sep 10:14

dsh-wechat-clawbot 0.2.2

修正 0.2.1 里一个会让保鲜功能静默失效的判据错误。

0.2.1 的漏洞

0.2.1 把「往不存在的收件人发 /send」当成窗口探针(ret=-3=开 / ret=-2=关)。这是错的:腾讯在收件人不存在时会在「准备会话」之前就做参数校验,所以在任何窗口状态下都返回 ret=-3。

实测反证(发布后立刻验证):POST /probe 报 window=open 的一秒后,一次完全不带 context_token 的真实发送仍然 ret=-2 prepare failed。→ 探针从来测不到窗口,0.2.1 的保鲜循环会把状态一直当成「开着」、永不提醒。

修复

  • POST /probe 不再充当窗口判据:改为「只验证上游可达」,返回 conclusive:false,并且不再改写 window-state.json。
  • 窗口状态只取真实发送的结果(成功=open / ret=-2=closed),这是唯一可靠信号。
  • 新增 keepaliveWarnHours(默认 2 小时,0=关):静默超过阈值时用桌面通道提醒续期,每个入站一次——因为窗口可能在我们观测到之前就已关闭。
  • 修掉跨 tick 漏出的旧 action 字段(上一轮的 dueWarnHours/dueNudgeHours 不再被重复执行)。

测试

npm test 18 项(window 8 + keepalive 7 + probe 3);离线 mock iLink 集成测 10 项覆盖「探针不改写状态」「真实发送决定开/关」。verify:full ✅。

安装 / 升级

dsh plugin --profile <desktop|web> add dsh-wechat-clawbot@0.2.2

升级后需重启 DSH 生效。无破坏性变更;旧调用方无需改动。

v0.2.1 — 会话窗口健康与内置保鲜提醒

Choose a tag to compare

@zhengjy01 zhengjy01 released this 19 Sep 05:02

dsh-wechat-clawbot 0.2.1

把「会话窗口健康 + 保鲜提醒」从本机手写脚本收进插件本体,修复「完成任务却收不到通知」的根因。

为什么

腾讯 iLink 只在用户「会话窗口」打开时接受主动推送;窗口只有用户能开(他从手机给机器人发一句话),机器人发出去的消息不给它续期。窗口关闭后一律 ret=-2 prepare failed,而网关 /status 的 phase 仍是 logged_in——本地状态不反映出站可用性。

新增

  • 网关对每条入站消息落盘 <stateDir>/last-inbound.json(不能用 context-tokens.json 的 updatedAt——token 未变化时它跳过写入,时间会冻住)。
  • GET /window:窗口健康(window open/closed/unknown、lastInboundAt、age、最近一次发送/探测结果与 hint);/status 同步暴露。
  • POST /probe:往不存在的收件人发消息的无损探针(ret=-3 窗口开 / ret=-2 窗口关),不会给用户发任何消息。
  • /send 失败返回结构化原因:{ ok:false, reason, ret, window, hint, lastInboundAt, age },不再只有一句 ret=-2 prepare failed。
  • 插件内置保鲜循环(keepalive / keepaliveIntervalMinutes / keepaliveNudgeHours / keepaliveNotify):窗口「开→关」跳变时弹一次桌面通知提醒续期,已关则停止空探直到用户回话。全新机器安装即自带,不依赖本机脚本或 launchd。

修复

  • GET /api/dsh-wechat-bot/probe 补上 version 字段(此前 CHANGELOG 声称有、代码没有)。

安装 / 升级

dsh plugin --profile <desktop|web> add dsh-wechat-clawbot@0.2.1

升级后需重启 DSH 生效。无破坏性变更;旧调用方无需改动。实测:verify:full 通过(隔离 DSH_HOME + tarball 安装 + 探针 200 + 客户端 bundle + 30s 稳定)。

v0.2.0 — 独立维护线首个版本(主动推送 context_token 修复 + 单一包安装)

Choose a tag to compare

@zhengjy01 zhengjy01 released this 17 Sep 14:01

安装 / Install

dsh plugin --profile <desktop|web> add dsh-wechat-clawbot@0.2.0
# 或从 GitHub:
dsh plugin --profile <desktop|web> add github:zhengjy01/dsh-wechat-clawbot

装完必须重启 DSH(插件树只在启动时读取)。

这是本仓库作为独立维护线接手上游 lubaiUwU/DSH-WeChatClawBot 后的首个版本。
上游最后提交 2026-08-17(b817fc9),维护者自 2026-08-18 起无活动。


本仓库(zhengjy01/dsh-wechat-clawbot)作为独立维护线接手上游 lubaiUwU/DSH-WeChatClawBot 后的首个版本(上游最后提交 b817fc9,2026-08-17;维护者自 2026-08-18 起无活动)。

⚠️ 迁移说明(从上游或从本地软链安装迁移过来,必读)

  1. 包结构变了:从「monorepo + file: 子包」变成单一 npm 包。
    上游的 dsh-wechat-bot 通过 file:../dsh-wechat-bridge 引用同仓子包,并带 prepare / postinstall 构建脚本 —— 在 pnpm 10 下 dsh plugin add 会直接装不上(解析不到 file: 子包,或 build scripts 被 allowBuilds 拦截)。本版把宿主入口改为根 index.js 转出、把 bridge 改为相对导入、去掉全部构建脚本,因此安装成功即进入 dsh.profile.bundles。
  2. 安装方式变了:不再用「克隆 + 软链」挂载。
    dsh plugin --profile <desktop|web> add github:zhengjy01/dsh-wechat-clawbot
    若你之前用上游的 install-wechat.sh 在 profiles/<p>/node_modules/ 下建过 dsh-wechat-bot / dsh-client-wechat-ui / dsh-wechat-bridge 三个软链,请删掉它们,并移除 profile cordis.patch.yml 里手工 insert 的 wechat-bot / wechat-ui 两行 —— 本包的 bundle 会自带这一行,重复会 duplicate id。
  3. 必须重启 DSH。 插件树(bundle 列表)只在启动时读取;不重启不会挂上新包。
  4. 本包地址前缀不变,仍是 /api/dsh-wechat-bot/*,配置文件名仍是 ~/.dsh-wechat/* —— 按发布规范保留,避免丢既有登录凭证与配置。

新增 (Added)

  • GET /api/dsh-wechat-bot/probe 宿主存活探针:返回 {ok, plugin, version, gatewayPort, modelPort},供可移植性验证与外部健康检查使用(ctx.inject 了 webServer,headless 下也不受阻)。
  • 端口与状态目录可用环境变量覆盖:DSH_WECHAT_GATEWAY_PORT、DSH_WECHAT_MODEL_PORT、DSH_WECHAT_STATE_DIR(默认值不变)。隔离的可移植性验证依赖它们避开主实例占用的端口。
  • 发布前门禁:scripts/portability.mjs + PORTABILITY-SOP.md + npm run verify / verify:full / verify:quick。
  • 双语 README:README.md(英文)+ README.zh.md(中文),顶部互切。
  • 主动推送上下文持久化(见下方修复 ② 的落地文件):<stateDir>/context-tokens.json。

修复 (Fixed)

  • 登录循环覆盖已登录状态,导致回复发不出去("没反应")(上游 b817fc9 之后的本地修复,提交 6668793):
    重复/强制登录会启动新的登录循环但从不取消旧的;旧循环收到 expired 后会把已经 logged_in 的全局状态改回 waiting_qrcode,于是 /send 被自身状态守卫拒绝,DSH 已生成的回复被静默丢弃。修复:state.loginGen 轮次隔离(bailIfSuperseded 静默退出、setPhaseCurrent 只有当前轮次能写状态)、/send 放宽为「只要还持有 token 就允许发送」、modelServer 补 error 监听(端口占用不再终结 DSH 宿主)。
  • 主动推送在距上次用户交互一段时间后一律 502 ret=-2 prepare failed(提交 273601d):
    iLink 的 sendmessage 需要「打开的会话上下文(context_token)」。入站消息带该 token,但原网关只在自动回复那条路径透传,其余地方直接丢弃,因此所有 fire-and-forget 主动推送(会话日报、微信通知、任务派发器通知)在上下文过期后必然失败 —— 表现为「微信通道突然坏了」,实际与 token 有效性、网络、monitor 长轮询统统无关。修复:把每个发送者最近一次的 context_token 落盘(<stateDir>/context-tokens.json,0600,最多保留 50 个发送者,token 未变化则跳过写入),/send 在调用方未显式提供 contextToken 时自动复用;调用方仍可显式覆盖。一处修复,日报/通知/派发器全部受益,脚本侧无需改动。

变更 (Changed)

  • 宿主内引用 dsh-wechat-bridge 由 peer 子包改为相对导入,安装路径不再依赖配套软链垫片(scripts/link-peer-shims.mjs 仅本地软链开发模式需要)。
  • 单一组合包:根 index.js 转出宿主插件,dsh.client + exports["./client"] 声明悬浮球 bundle(浏览器端从本包发现 dsh-wechat-clawbot/client.js)。

未改动(与上游一致)

扫码登录、悬浮球面板、联系人白名单、ClawBot 专用模型配置、独立对话区与 /new 切换等行为全部保持上游原样。


发布前门禁:npm run verify:full ✅ 通过(隔离 DSH_HOME + 全新 profile + tarball 安装、不走 link:;宿主探针 /api/dsh-wechat-bot/probe 200;客户端 bundle 进 __DSH_BOOT__.entries;30s 稳定性观察无掉线)。
兼容性:要求 DeepSeek Harness ≥ 0.1.5-rc.1(dsh.engines.dsh),实测 0.1.5-rc.1;Node ≥ 22.19。