变更日志
本项目遵循 Keep a Changelog 格式。
[未发布]
新增
- 新增基于仓库 Markdown 生成的多语言文档站点,通过 GitHub Pages 发布: 使用 VitePress 提供中英文导航、本地搜索、深色模式与移动端布局,每个页面 同时提供 HTML 与 Markdown 原文,并输出
llms.txt与llms-full.txt供大模型索引最新文档。
修复
- 入站 getUpdates 双投递: ordinary / approval 两条 admission 车道在处理前通过 OpenClaw
createClaimableDedupe(账号隔离的resolveFilePath,落在openclaw-weixin/replay-dedupe/,兼容最低宿主2026.6.1)认领稳定去重键 (message_id→client_id→seq→ 正文指纹),成功后写入 24 小时墓碑, 避免 iLink 长轮询至少一次投递(约 1 秒重放)以及长任务卡住后的更长窗口重投 把同一条消息跑两遍 AI,并在进程重启后仍生效。失败与 abort 会 release 以便 重试。进行中的重放会立刻释放 admission 车道,在车道外观察持有者,仅在 release 时重新入队,避免挡住后续不同消息。认领成功后的每一步都在 claim 生命周期内。Fallback 优先用 itemmsg_id摘要,绝不只按发送者建键。重复 投递日志只记录非敏感的 identity 种类。该窗口是重放去重 / 墓碑窗口,不 会吞掉用户故意再发且带有新message_id的消息。存在传输层 id 时MessageSid使用同一稳定键。移植自 Tencent/openclaw-weixin#240; 跟踪 NewFuture/openclaw-weixin#36。
[3.0.1] - 2026-08-02
变更
- 将 npm 发布绑定到受保护的
npm-publishenvironment;自动检查全部通过后需由 仓库管理员审批,且 OIDC 发布权限仅授予审批后的发布 job。 - npmjs 发布成功后由同一工作流同步发布 GitHub Packages 镜像
@newfuture/openclaw-weixin,再创建使用中英文变更日志说明的 GitHub Release; 重试时会分别跳过已存在的包版本并补齐缺失目标;包括 registry 为空的情况,前一 仓库版本尚未完成镜像时不会发布后续 GitHub Packages 版本。 - 将最低支持的 OpenClaw 宿主扩展至
2026.6.1,保留2026.7.1作为常规开发 基线,并增加最低宿主版本的完整 CI 构建与测试。
[3.0.0] - 2026-07-31
新增
- exec 审批提示现在会分别展示便于复制的
/approve代码块:转发提示会按 OpenClaw 允许的决策附加各个短 ID 操作,直接提示则会将Other options下的每条命令拆成 独立代码块。
变更
- 将社区 npm 包与插件版本更新至
3.0.0,作为统一使用openclaw-weixin单一标识后的首个版本。 - 将仓库、npm 包、插件和 channel 名称统一为
openclaw-weixin,并简化为仅发布 一个包。 - 将 MIT 许可证正文统一为标准格式,并随包发布说明性
NOTICE,保留腾讯上游 署名及社区修改声明。 - 增加发布元数据门禁,并在
mainCI 全部通过后幂等协调发布标签、npm 状态及 发布任务,将标签固定在版本转换提交并按版本顺序触发对应发布。 - 将中文设为默认 README,将英文版移至
README_EN.md,并保留README.zh_CN.md作为兼容入口。 - 将最低支持的 OpenClaw 宿主提升至
2026.7.1,并使运行时检查、包元数据、 开发环境及 CI 的 Node.js 最低版本与该版本保持一致。 - 将插件安装与腾讯官方包原位替换统一为同一条
--force命令,并单独说明账号 接入、重载验证及 Agent 安装流程;详细用法和协议参考移至随包发布的docs/目录。
安全
- 将存在漏洞的开发期传递依赖覆盖为已修复版本,并在 CI 与 npm 发布流程中 增加中危及以上依赖审计门禁。
[2.4.6] - 2026-07-23
变更
- 基于腾讯
@tencent-weixin/openclaw-weixin准备首个社区维护的未加 scope npm 发行包openclaw-weixin。 - 保留内部
openclaw-weixin插件/channel ID、配置键与状态目录,支持原位 切换。 - 增加社区仓库元数据、包内容检查和 npm Trusted Publishing 工作流。
- 将运行时兼容检查与文档统一为 OpenClaw
>=2026.5.12、Node.js>=22。
[2.4.5] - 2026-06-22
新增
classifyFetchError— 网络错误分类:src/api/api.ts新增classifyFetchError工具函数,将 fetch 级错误分类为dns/tcp/tls/timeout/unknown。apiGetFetch与apiPostFetch在失败时输出结构化日志(type, description, code),便于排查网络问题。覆盖 ENOTFOUND、ECONNREFUSED、ETIMEDOUT、SSL/TLS、AbortError 等场景的完整测试。sendMessage返回值校验:sendMessage现在解析服务端返回的SendMessageResp(ret/errmsg),ret非零时抛错,避免消息发送静默失败。
变更
SESSION_EXPIRED_ERRCODE→STALE_TOKEN_ERRCODE: 在src/api/session-guard.ts中重命名,更准确地描述 token 过期(-14 表示 token 失效,而非 session 过期)。monitor.ts与测试中所有引用同步更新。- 错误日志改进:
monitor.ts中getUpdates的错误日志使用classifyFetchError输出分类信息(type, description, code)。monitor.ts移除重复的errLog日志行,仅保留aLog.error。- CDN 上传失败日志(
cdn-upload.ts)增加脱敏 URL 和错误 cause 信息。 downloadRemoteImageToTemp(upload.ts)增加 fetch 网络错误详情日志。- API GET/POST fetch 失败日志(
api.ts)增加脱敏 URL、超时设置及错误分类信息。
- 最低宿主版本升级:
peerDependencies.openclaw和install.minHostVersion从>=2026.3.22升至>=2026.5.12。
新增(开发/工程)
outbound-hooks.test.ts: 新增测试文件,覆盖applyWeixinMessageSendingHook(无 hook、内容修改、取消、错误容错)和emitWeixinMessageSent(无 hook、成功、失败走 fire-and-forget)各场景。
修复
pairing.test.tsmock 路径:vi.mock目标从"openclaw/plugin-sdk"修正为"openclaw/plugin-sdk/infra-runtime"。api.test.tssendMessage 测试 mock: 成功用例的 mock 返回值从""改为"{}",与sendMessage新增的响应解析逻辑一致。
[2.4.4] - 2026-05-22
新增
- 工具调用进度消息: 模型执行 tool 时,发送
TOOL_CALL_START/TOOL_CALL_RESULT进度消息,可通过replyProgressMessages开关控制(默认开启)。 - 请求中断信号支持:
apiPostFetch/getUpdates现在接受外部的AbortSignal。当网关停止或热重载频道时,正在进行的 long-poll 请求会被立即取消,无需等待服务端超时。
[2.4.3] - 2026-05-08
修复
iLink-App-Id/iLink-App-ClientVersion请求头在生产环境为空 /0。readPackageJson用固定的../../从import.meta.url推算package.json,但 TypeScript 构建(tsconfig.include同时包含index.ts和src/**/*.ts)实际产物是dist/src/api/api.js(多出一层src/),导致解析到不存在的dist/package.json,catch 返回{}。改为从当前模块所在目录向上逐级查找,并通过name包含openclaw-weixin或存在ilink_appid字段来确认是本插件自己的package.json,同时兼容开发态(src/api/)和发布态(dist/src/api/)布局。src/api/api.test.ts新增 5 个用例覆盖编译产物布局、开发布局、途经node_modules/<dep>/package.json不被误识别、找不到时返回{}、坏 JSON 容错继续向上查找。openclaw channels login在 "已连接过此 OpenClaw" 场景下被误判为失败。 服务端返回binded_redirect时本地凭据其实仍有效,但旧逻辑返回connected: false,channel.ts的auth.login据此throw,CLI 非零退出,导致openclaw-weixin-installer等自动化脚本误打印"首次连接未完成"。WeixinQrWaitResult新增alreadyConnected字段,QR 轮询在binded_redirect时置为true;auth.login据此仅记录消息、不抛错,CLI 以 0 退出。
[2.4.2] - 2026-05-07
修复
- Node 24 / undici 兼容性——所有请求
TypeError: fetch failed。 从buildHeaders中移除手动设置的Content-Length。Node 24 自带的 undici 不允许调用方预设Content-Length,会以UND_ERR_INVALID_ARG: invalid content-length header拒绝整个请求,导致所有 CGI 调用失败。改由fetch根据请求体自动计算,恢复在 Node 24 下的网络调用。 - OpenClaw ≥ 2026.5.x——微信 runtime 初始化超时无限重启。 移除模块作用域的
pluginRuntime全局变量(同时删掉src/runtime.ts),改为按调用从网关 ctx 中读取ctx.channelRuntime。原先的全局是在插件注册阶段写入的,但较新宿主改为按调用注入 runtime surface,启动时拿不到/拿到旧值,channel 启动一直超时进而被反复重启。
移除
- 冗余脚本与入口: 删除调试用的
scripts/test-full-upload.ts/scripts/test-upload-url.ts,以及遗留的index.ts转发文件。对调用方无行为变更。
[2.4.1] - 2026-05-04
新增
- npm 包内携带 dist 产物作为 channel 入口:
package.json的files加入dist/,openclaw.runtimeExtensions设为["./dist/index.js"];宿主直接加载预编译的 JS 入口,不再依赖装包时的 TypeScript 源码,避免在较严格的宿主版本上出现requires compiled runtime output for TypeScript entry index.ts错误。 openclaw.plugin.json频道配置: 在openclaw.plugin.json中声明channels与channelConfigs,使较新宿主(≥ 2026.4.x)能直接渲染频道选择 UI,无需回退到package.json#openclaw。
[2.3.1] - 2026-04-28
新增
bot_agent请求字段: 上行 CGI 现在携带由上层应用提供的bot_agent(类似 UA 的name/version (comment)语法,支持多个 product),按上层应用的 channel 配置传入;src/api/api.ts中的sanitizeBotAgent负责清洗与长度上限,缺失或不合法时回落为OpenClaw。- 扫码时上送
local_token_list:fetchQRCode现在带上本地最近 10 个bot_token,让服务端识别"已绑定到本端"的 bot 并下发binded_redirect,避免重复发会话。 - 配对码登录流程: 服务端要求二次校验时(
need_verifycode/verify_code_blocked),waitForWeixinLogin通过 stdin 提示用户输入verify_code并做有限次重试。 binded_redirect处理: QR 轮询新增分支,输出✅ 已连接过此 OpenClaw,无需重复连接。并优雅返回。- 连接状态通知(start/stop):
gateway.startAccount在 provider 注册后调用notifyStart,新增的gateway.stopAccounthook 调用notifyStop,便于上游微信服务端对账户在线状态进行对账。
变更
- 扫码登录文案: 调整 QR / 扫码相关的提示文案;同时移除
fetchQRCode/startWeixinLoginWithQr的客户端超时,长轮询仅受服务端与网络栈限制。
[2.1.10] - 2026-04-24
新增
- 连接状态通知(start/stop)首次引入: 账号启动时发送
notifyStart,关闭时通过新的gateway.stopAccounthook 发送notifyStop。该能力在后续 2.3.x 中保留。
[2.1.9] - 2026-04-20
新增
- 外发 hook 支持: 为所有外发路径(
sendText、sendMedia、process-message中的入站回复deliver)接入message_sending(发送前拦截/修改)和message_sent(发送后通知)hook。hook 逻辑抽取至共享模块src/messaging/outbound-hooks.ts。
变更
- 清理: 移除
sendWeixinOutbound签名中未使用的mediaUrl参数。
[2.1.8] - 2026-04-07
变更
- Markdown 过滤器:
StreamingMarkdownFilter放开了更多 Markdown 格式的保留。
[2.1.7] - 2026-04-07
修复
- 插件注册重入:
channel.ts中将monitorWeixinProvider改为在startAccount内部懒加载(await import(...)),避免插件注册阶段提前拉取 monitor → process-message → command-auth 依赖链,导致 plugin/provider registry 重入。 - 初始化副作用:
process-message.ts中将resolveSenderCommandAuthorizationWithRuntime/resolveDirectDmAuthorizationOutcome改为懒加载,避免模块初始化时触发宿主的ensureContextWindowCacheLoaded副作用,进而导致loadOpenClawPlugins重入。
变更
- tool-call 外发路径:
sendWeixinOutbound现在对发送文本应用StreamingMarkdownFilter,与process-message中的 model-output 路径保持一致。
[2.1.4] - 2026-04-03
变更
- 扫码登录: 移除
get_bot_qrcode的客户端超时,请求不再因固定时限被 abort(仍受服务端与网络栈限制)。
[2.1.3] - 2026-04-02
新增
StreamingMarkdownFilter(src/messaging/markdown-filter.ts):外发文本由原先markdownToPlainText整段剥离 Markdown,改为流式逐字符过滤;对 Markdown 从完全不支持变为部分支持。
变更
- 外发文本:
process-message在每次deliver时用StreamingMarkdownFilter(feed/flush)处理回复,替代markdownToPlainText。
移除
- 从
src/messaging/send.ts删除markdownToPlainText(相关用例从send.test.ts迁至markdown-filter.test.ts)。
[2.1.2] - 2026-04-02
变更
- 登录后配置刷新: 每次微信登录成功后,在
openclaw.json中更新channels.openclaw-weixin.channelConfigUpdatedAt(ISO 8601),让网关从磁盘重新加载配置;不再写入空的accounts: {}占位。 - 扫码登录:
get_bot_qrcode客户端超时由 5s 调整为 10s。 - 文档: 卸载说明改为使用
openclaw plugins uninstall @tencent-weixin/openclaw-weixin,与插件 CLI 一致。 - 日志:
debug-check日志不再输出stateDir/OPENCLAW_STATE_DIR。
移除
openclaw-weixin子命令(删除src/weixin-cli.ts及index.ts中的注册)。请使用宿主自带的openclaw plugins uninstall …卸载流程。
修复
- 解决在 OpenClaw 2026.3.31 及更新版本上安装插件时出现的 dangerous code pattern 提示(宿主插件安装 / 静态检查)。