openclaw-weixin 2.4.6 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,175 +1,192 @@
1
- # Changelog
1
+ # 变更日志
2
2
 
3
- [简体中文](CHANGELOG.zh_CN.md)
3
+ [English](CHANGELOG_EN.md)
4
4
 
5
- This project follows the [Keep a Changelog](https://keepachangelog.com/) format.
5
+ 本项目遵循 [Keep a Changelog](https://keepachangelog.com/) 格式。
6
6
 
7
- ## [Unreleased]
7
+ ## [未发布]
8
8
 
9
- ### Changed
9
+ ## [3.0.0] - 2026-07-31
10
10
 
11
- - Raised the minimum supported OpenClaw host to `2026.7.1` and aligned the
12
- runtime guard, package metadata, development environment, and CI Node.js
13
- floors with that release.
11
+ ### 新增
14
12
 
15
- ### Security
13
+ - exec 审批提示现在会分别展示便于复制的 `/approve` 代码块:转发提示会按 OpenClaw
14
+ 允许的决策附加各个短 ID 操作,直接提示则会将 `Other options` 下的每条命令拆成
15
+ 独立代码块。
16
16
 
17
- - Overrode vulnerable transitive development dependencies with patched versions
18
- and added a moderate-or-higher dependency audit gate to CI and npm releases.
17
+ ### 变更
18
+
19
+ - 将社区 npm 包与插件版本更新至 `3.0.0`,作为统一使用
20
+ `openclaw-weixin` 单一标识后的首个版本。
21
+ - 将仓库、npm 包、插件和 channel 名称统一为 `openclaw-weixin`,并简化为仅发布
22
+ 一个包。
23
+ - 将 MIT 许可证正文统一为标准格式,并随包发布说明性 `NOTICE`,保留腾讯上游
24
+ 署名及社区修改声明。
25
+ - 增加发布元数据门禁,并在 `main` CI 全部通过后幂等协调发布标签、npm 状态及
26
+ 发布任务,将标签固定在版本转换提交并按版本顺序触发对应发布。
27
+ - 将中文设为默认 README,将英文版移至 `README_EN.md`,并保留
28
+ `README.zh_CN.md` 作为兼容入口。
29
+ - 将最低支持的 OpenClaw 宿主提升至 `2026.7.1`,并使运行时检查、包元数据、
30
+ 开发环境及 CI 的 Node.js 最低版本与该版本保持一致。
31
+ - 将插件安装与腾讯官方包原位替换统一为同一条 `--force` 命令,并单独说明账号
32
+ 接入、重载验证及 Agent 安装流程;详细用法和协议参考移至随包发布的 `docs/`
33
+ 目录。
34
+
35
+ ### 安全
36
+
37
+ - 将存在漏洞的开发期传递依赖覆盖为已修复版本,并在 CI 与 npm 发布流程中
38
+ 增加中危及以上依赖审计门禁。
19
39
 
20
40
  ## [2.4.6] - 2026-07-23
21
41
 
22
- ### Changed
42
+ ### 变更
23
43
 
24
- - Prepared the first community-maintained npm distribution as the unscoped
25
- `openclaw-weixin` package, derived from Tencent's
26
- `@tencent-weixin/openclaw-weixin`.
27
- - Preserved the internal `openclaw-weixin` plugin/channel id, configuration
28
- keys, and state paths for in-place migration.
29
- - Added community repository metadata, package-content checks, and an
30
- npm Trusted Publishing workflow.
31
- - Aligned the runtime compatibility guard and documentation with OpenClaw
32
- `>=2026.5.12` and Node.js `>=22`.
44
+ - 基于腾讯 `@tencent-weixin/openclaw-weixin` 准备首个社区维护的未加 scope
45
+ npm 发行包 `openclaw-weixin`。
46
+ - 保留内部 `openclaw-weixin` 插件/channel ID、配置键与状态目录,支持原位
47
+ 切换。
48
+ - 增加社区仓库元数据、包内容检查和 npm Trusted Publishing 工作流。
49
+ - 将运行时兼容检查与文档统一为 OpenClaw `>=2026.5.12`、Node.js `>=22`。
33
50
 
34
51
  ## [2.4.5] - 2026-06-22
35
52
 
36
- ### Added
53
+ ### 新增
37
54
 
38
- - **`classifyFetchError` — network error classification:** New `classifyFetchError` utility in `src/api/api.ts` classifies fetch-level errors into `dns` / `tcp` / `tls` / `timeout` / `unknown`. `apiGetFetch` and `apiPostFetch` now log structured error details (type, description, code) on failure, making network troubleshooting significantly easier. Includes full test coverage for ENOTFOUND, ECONNREFUSED, ETIMEDOUT, SSL/TLS, AbortError, and more.
39
- - **`sendMessage` response validation:** `sendMessage` now parses the server response (`SendMessageResp` with `ret` / `errmsg`) and throws on non-zero `ret`, preventing silent delivery failures.
55
+ - **`classifyFetchError` — 网络错误分类:** `src/api/api.ts` 新增 `classifyFetchError` 工具函数,将 fetch 级错误分类为 `dns` / `tcp` / `tls` / `timeout` / `unknown`。`apiGetFetch` 与 `apiPostFetch` 在失败时输出结构化日志(type, description, code),便于排查网络问题。覆盖 ENOTFOUND、ECONNREFUSED、ETIMEDOUT、SSL/TLS、AbortError 等场景的完整测试。
56
+ - **`sendMessage` 返回值校验:** `sendMessage` 现在解析服务端返回的 `SendMessageResp`(`ret` / `errmsg`),`ret` 非零时抛错,避免消息发送静默失败。
40
57
 
41
- ### Changed
58
+ ### 变更
42
59
 
43
- - **`SESSION_EXPIRED_ERRCODE` → `STALE_TOKEN_ERRCODE`:** Renamed in `src/api/session-guard.ts` to more accurately describe the token-stale condition (the error code -14 indicates a stale/expired token, not a session expiry). All references in `monitor.ts` and tests updated.
44
- - **Error logging improvements:**
45
- - `getUpdates` errors in `monitor.ts` now include `classifyFetchError` classification (type, description, code).
46
- - Removed duplicate `errLog` lines in `monitor.ts`; only `aLog.error` remains.
47
- - CDN upload failure logs (`cdn-upload.ts`) now include redacted URL and error cause.
48
- - `downloadRemoteImageToTemp` (`upload.ts`) now logs detailed fetch network errors with cause.
49
- - API GET/POST fetch failures (`api.ts`) now log redacted URL, timeout, and error classification.
50
- - **Minimum host version bumped:** `peerDependencies.openclaw` and `install.minHostVersion` raised from `>=2026.3.22` to `>=2026.5.12`.
60
+ - **`SESSION_EXPIRED_ERRCODE` → `STALE_TOKEN_ERRCODE`:** 在 `src/api/session-guard.ts` 中重命名,更准确地描述 token 过期(-14 表示 token 失效,而非 session 过期)。`monitor.ts` 与测试中所有引用同步更新。
61
+ - **错误日志改进:**
62
+ - `monitor.ts` 中 `getUpdates` 的错误日志使用 `classifyFetchError` 输出分类信息(type, description, code)。
63
+ - `monitor.ts` 移除重复的 `errLog` 日志行,仅保留 `aLog.error`。
64
+ - CDN 上传失败日志(`cdn-upload.ts`)增加脱敏 URL 和错误 cause 信息。
65
+ - `downloadRemoteImageToTemp`(`upload.ts`)增加 fetch 网络错误详情日志。
66
+ - API GET/POST fetch 失败日志(`api.ts`)增加脱敏 URL、超时设置及错误分类信息。
67
+ - **最低宿主版本升级:** `peerDependencies.openclaw` 和 `install.minHostVersion` 从 `>=2026.3.22` 升至 `>=2026.5.12`。
51
68
 
52
- ### Added (Dev/Engineering)
69
+ ### 新增(开发/工程)
53
70
 
54
- - **`outbound-hooks.test.ts`:** New test file covering `applyWeixinMessageSendingHook` (no hooks, content modification, cancellation, error recovery) and `emitWeixinMessageSent` (no hooks, success, failure with fire-and-forget) scenarios.
71
+ - **`outbound-hooks.test.ts`:** 新增测试文件,覆盖 `applyWeixinMessageSendingHook`(无 hook、内容修改、取消、错误容错)和 `emitWeixinMessageSent`(无 hook、成功、失败走 fire-and-forget)各场景。
55
72
 
56
- ### Fixed
73
+ ### 修复
57
74
 
58
- - **`pairing.test.ts` mock path:** `vi.mock` target corrected from `"openclaw/plugin-sdk"` to `"openclaw/plugin-sdk/infra-runtime"`.
59
- - **`api.test.ts` sendMessage mock response:** Success test case mock now returns `"{}"` instead of `""`, matching the updated `sendMessage` logic that parses the response body.
75
+ - **`pairing.test.ts` mock 路径:** `vi.mock` 目标从 `"openclaw/plugin-sdk"` 修正为 `"openclaw/plugin-sdk/infra-runtime"`。
76
+ - **`api.test.ts` sendMessage 测试 mock:** 成功用例的 mock 返回值从 `""` 改为 `"{}"`,与 `sendMessage` 新增的响应解析逻辑一致。
60
77
 
61
78
  ## [2.4.4] - 2026-05-22
62
79
 
63
- ### Added
80
+ ### 新增
64
81
 
65
- - **Tool-call progress messages:** `WeixinReplyProgressSender` sends `TOOL_CALL_START` / `TOOL_CALL_RESULT` progress messages when the model executes tools. Configurable via the `replyProgressMessages` channel option (default: `true`).
66
- - **Abort signal support for in-flight requests:** `apiPostFetch` / `getUpdates` now accept an external `AbortSignal`. When the gateway stops or hot-reloads a channel, the in-flight long-poll is cancelled immediately instead of waiting for the server-side timeout.
82
+ - **工具调用进度消息:** 模型执行 tool 时,发送 `TOOL_CALL_START` / `TOOL_CALL_RESULT` 进度消息,可通过 `replyProgressMessages` 开关控制(默认开启)。
83
+ - **请求中断信号支持:** `apiPostFetch` / `getUpdates` 现在接受外部的 `AbortSignal`。当网关停止或热重载频道时,正在进行的 long-poll 请求会被立即取消,无需等待服务端超时。
67
84
 
68
85
  ## [2.4.3] - 2026-05-08
69
86
 
70
- ### Fixed
87
+ ### 修复
71
88
 
72
- - **`iLink-App-Id` / `iLink-App-ClientVersion` headers were empty / `0` in production.** `readPackageJson` resolved `package.json` via a fixed `../../` from `import.meta.url`, but the TypeScript build (with `index.ts` plus `src/**/*.ts` in `tsconfig.include`) emits `dist/src/api/api.js` (extra `src/` segment), so the resolved path landed on the non-existent `dist/package.json` and the catch returned `{}`. Replaced with a walk-up that searches for the plugin's own `package.json` (validated by `name` containing `openclaw-weixin` or by the presence of `ilink_appid`), tolerating both dev (`src/api/`) and built (`dist/src/api/`) layouts. Adds tests in `src/api/api.test.ts` covering the compiled layout, dev layout, nested `node_modules/<dep>/package.json` shadowing, missing manifest, and malformed manifest.
73
- - **`openclaw channels login` exited non-zero when the bot was already bound to this OpenClaw**, which caused automated installers (e.g. `openclaw-weixin-installer`) to report a misleading "首次连接未完成" message and continue past a successful state. The QR poller now returns `alreadyConnected: true` for the server's `binded_redirect` status, and `auth.login` in `channel.ts` treats it as a successful no-op (no save, no throw) so the CLI exits cleanly.
89
+ - **`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 容错继续向上查找。
90
+ - **`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 退出。
74
91
 
75
92
  ## [2.4.2] - 2026-05-07
76
93
 
77
- ### Fixed
94
+ ### 修复
78
95
 
79
- - **Node 24 / undici compatibility — `TypeError: fetch failed` on every request.** Drop the manually-set `Content-Length` header from `buildHeaders`. The bundled undici in Node 24 rejects pre-set `Content-Length` with `UND_ERR_INVALID_ARG: invalid content-length header`, breaking all CGI calls. Letting `fetch` compute it from the request body restores network calls on Node 24.
80
- - **OpenClaw ≥ 2026.5.x — Weixin runtime initialization timeout restart loop.** Replace the module-scope `pluginRuntime` global (and remove `src/runtime.ts` along with it) with the `ctx.channelRuntime` injected by the gateway per call. The previous global was set during plugin registration, but newer hosts inject a per-call runtime surface, so the global was missing/stale at startup and the channel kept timing out and restarting.
96
+ - **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 下的网络调用。
97
+ - **OpenClaw ≥ 2026.5.x——微信 runtime 初始化超时无限重启。** 移除模块作用域的 `pluginRuntime` 全局变量(同时删掉 `src/runtime.ts`),改为按调用从网关 ctx 中读取 `ctx.channelRuntime`。原先的全局是在插件注册阶段写入的,但较新宿主改为按调用注入 runtime surface,启动时拿不到/拿到旧值,channel 启动一直超时进而被反复重启。
81
98
 
82
- ### Removed
99
+ ### 移除
83
100
 
84
- - **Dead scripts and shims:** `scripts/test-full-upload.ts` / `scripts/test-upload-url.ts` debug scripts and the unused legacy `index.ts` re-exports. No behavior change for consumers.
101
+ - **冗余脚本与入口:** 删除调试用的 `scripts/test-full-upload.ts` / `scripts/test-upload-url.ts`,以及遗留的 `index.ts` 转发文件。对调用方无行为变更。
85
102
 
86
103
  ## [2.4.1] - 2026-05-04
87
104
 
88
- ### Added
105
+ ### 新增
89
106
 
90
- - **Ship compiled runtime in the npm tarball:** `dist/` is added to `files` and `package.json#openclaw.runtimeExtensions` is set to `["./dist/index.js"]`. The host loads the prebuilt JS entry directly instead of relying on source-only TypeScript at install time, which avoids the `requires compiled runtime output for TypeScript entry index.ts` error on stricter host versions.
91
- - **`openclaw.plugin.json` channel config:** Declare `channels` and `channelConfigs` in `openclaw.plugin.json` so newer hosts (≥ 2026.4.x) can render the channel selection UI without falling back to `package.json#openclaw`.
107
+ - **npm 包内携带 dist 产物作为 channel 入口:** `package.json` 的 `files` 加入 `dist/`,`openclaw.runtimeExtensions` 设为 `["./dist/index.js"]`;宿主直接加载预编译的 JS 入口,不再依赖装包时的 TypeScript 源码,避免在较严格的宿主版本上出现 `requires compiled runtime output for TypeScript entry index.ts` 错误。
108
+ - **`openclaw.plugin.json` 频道配置:** 在 `openclaw.plugin.json` 中声明 `channels` 与 `channelConfigs`,使较新宿主(≥ 2026.4.x)能直接渲染频道选择 UI,无需回退到 `package.json#openclaw`。
92
109
 
93
110
  ## [2.3.1] - 2026-04-28
94
111
 
95
- ### Added
112
+ ### 新增
96
113
 
97
- - **`bot_agent` request field:** Outgoing CGI requests now carry an upstream-app-supplied `bot_agent` (UA-style `name/version (comment)` grammar, multi-product allowed). Configurable per upstream app via channel config and sanitized by `sanitizeBotAgent` in `src/api/api.ts`; falls back to `OpenClaw` when missing or invalid.
98
- - **`local_token_list` on QR fetch:** `fetchQRCode` now posts the most recent local `bot_token`s (up to 10), enabling the server to recognize already-bound bots and reply with `binded_redirect` instead of issuing a duplicate session.
99
- - **Pair-code login flow:** Support entering a pair-code (`verify_code`) when the QR scan triggers a server-side challenge; `waitForWeixinLogin` handles `need_verifycode` / `verify_code_blocked` states with a stdin prompt and bounded retries.
100
- - **`binded_redirect` handling:** New status branch in QR polling that prints `✅ 已连接过此 OpenClaw,无需重复连接。` and returns gracefully when the scanned bot is already bound to this OpenClaw.
101
- - **Connection status notify (start/stop):** Emit `notifyStart` from `gateway.startAccount` (after the provider is announced) and `notifyStop` from a new `gateway.stopAccount` hook, so the upstream Weixin server can reconcile per-account online state.
114
+ - **`bot_agent` 请求字段:** 上行 CGI 现在携带由上层应用提供的 `bot_agent`(类似 UA 的 `name/version (comment)` 语法,支持多个 product),按上层应用的 channel 配置传入;`src/api/api.ts` 中的 `sanitizeBotAgent` 负责清洗与长度上限,缺失或不合法时回落为 `OpenClaw`。
115
+ - **扫码时上送 `local_token_list`:** `fetchQRCode` 现在带上本地最近 10 个 `bot_token`,让服务端识别"已绑定到本端"的 bot 并下发 `binded_redirect`,避免重复发会话。
116
+ - **配对码登录流程:** 服务端要求二次校验时(`need_verifycode` / `verify_code_blocked`),`waitForWeixinLogin` 通过 stdin 提示用户输入 `verify_code` 并做有限次重试。
117
+ - **`binded_redirect` 处理:** QR 轮询新增分支,输出 `✅ 已连接过此 OpenClaw,无需重复连接。` 并优雅返回。
118
+ - **连接状态通知(start/stop):** `gateway.startAccount` 在 provider 注册后调用 `notifyStart`,新增的 `gateway.stopAccount` hook 调用 `notifyStop`,便于上游微信服务端对账户在线状态进行对账。
102
119
 
103
- ### Changed
120
+ ### 变更
104
121
 
105
- - **QR login UX:** Reword the QR/scan prompts and remove the client-side timeout from `fetchQRCode` / `startWeixinLoginWithQr` — only server / stack limits now bound the long-poll.
122
+ - **扫码登录文案:** 调整 QR / 扫码相关的提示文案;同时移除 `fetchQRCode` / `startWeixinLoginWithQr` 的客户端超时,长轮询仅受服务端与网络栈限制。
106
123
 
107
124
  ## [2.1.10] - 2026-04-24
108
125
 
109
- ### Added
126
+ ### 新增
110
127
 
111
- - **Connection status notify (start/stop) — initial introduction:** `notifyStart` on account startup and `notifyStop` on shutdown via the new `gateway.stopAccount` hook. (Carried into the 2.3.x line as well.)
128
+ - **连接状态通知(start/stop)首次引入:** 账号启动时发送 `notifyStart`,关闭时通过新的 `gateway.stopAccount` hook 发送 `notifyStop`。该能力在后续 2.3.x 中保留。
112
129
 
113
130
  ## [2.1.9] - 2026-04-20
114
131
 
115
- ### Added
132
+ ### 新增
116
133
 
117
- - **Outbound hook support:** Add `message_sending` (pre-send interception/modification) and `message_sent` (post-send notification) hook integration for all outbound paths — `sendText`, `sendMedia`, and the inbound-reply `deliver` in `process-message`. Hook logic is extracted into a shared `src/messaging/outbound-hooks.ts` module.
134
+ - **外发 hook 支持:** 为所有外发路径(`sendText`、`sendMedia`、`process-message` 中的入站回复 `deliver`)接入 `message_sending`(发送前拦截/修改)和 `message_sent`(发送后通知)hook。hook 逻辑抽取至共享模块 `src/messaging/outbound-hooks.ts`。
118
135
 
119
- ### Changed
136
+ ### 变更
120
137
 
121
- - **Cleanup:** Remove unused `mediaUrl` parameter from `sendWeixinOutbound` signature.
138
+ - **清理:** 移除 `sendWeixinOutbound` 签名中未使用的 `mediaUrl` 参数。
122
139
 
123
140
  ## [2.1.8] - 2026-04-07
124
141
 
125
- ### Changed
142
+ ### 变更
126
143
 
127
- - **Markdown filter:** `StreamingMarkdownFilter` now preserves more Markdown constructs in outbound text.
144
+ - **Markdown 过滤器:** `StreamingMarkdownFilter` 放开了更多 Markdown 格式的保留。
128
145
 
129
146
  ## [2.1.7] - 2026-04-07
130
147
 
131
- ### Fixed
148
+ ### 修复
132
149
 
133
- - **Plugin registration re-entrance:** Lazy-import `monitorWeixinProvider` inside `startAccount` in `channel.ts` to avoid pulling in the monitor → process-message → command-auth chain at plugin registration time, which could re-enter the plugin/provider registry before the account starts.
134
- - **Initialization side effect:** Lazy-import `resolveSenderCommandAuthorizationWithRuntime` / `resolveDirectDmAuthorizationOutcome` in `process-message.ts` to prevent `ensureContextWindowCacheLoaded` from being triggered during module initialization, which caused `loadOpenClawPlugins` re-entrance.
150
+ - **插件注册重入:** `channel.ts` 中将 `monitorWeixinProvider` 改为在 `startAccount` 内部懒加载(`await import(...)`),避免插件注册阶段提前拉取 monitor → process-message → command-auth 依赖链,导致 plugin/provider registry 重入。
151
+ - **初始化副作用:** `process-message.ts` 中将 `resolveSenderCommandAuthorizationWithRuntime` / `resolveDirectDmAuthorizationOutcome` 改为懒加载,避免模块初始化时触发宿主的 `ensureContextWindowCacheLoaded` 副作用,进而导致 `loadOpenClawPlugins` 重入。
135
152
 
136
- ### Changed
153
+ ### 变更
137
154
 
138
- - **Tool-call outbound path:** `sendWeixinOutbound` now applies `StreamingMarkdownFilter` to the outbound text, consistent with the model-output path in `process-message`.
155
+ - **tool-call 外发路径:** `sendWeixinOutbound` 现在对发送文本应用 `StreamingMarkdownFilter`,与 `process-message` 中的 model-output 路径保持一致。
139
156
 
140
157
  ## [2.1.4] - 2026-04-03
141
158
 
142
- ### Changed
159
+ ### 变更
143
160
 
144
- - **QR login:** Remove client-side timeout for `get_bot_qrcode`; the request is no longer aborted on a fixed deadline (server / stack limits still apply).
161
+ - **扫码登录:** 移除 `get_bot_qrcode` 的客户端超时,请求不再因固定时限被 abort(仍受服务端与网络栈限制)。
145
162
 
146
163
  ## [2.1.3] - 2026-04-02
147
164
 
148
- ### Added
165
+ ### 新增
149
166
 
150
- - **`StreamingMarkdownFilter`** (`src/messaging/markdown-filter.ts`): outbound text no longer runs through whole-string `markdownToPlainText` stripping; a streaming character filter replaces it, so Markdown goes from **effectively unsupported** to **partially supported**.
167
+ - **`StreamingMarkdownFilter`**(`src/messaging/markdown-filter.ts`):外发文本由原先 `markdownToPlainText` 整段剥离 Markdown,改为流式逐字符过滤;**对 Markdown 从完全不支持变为部分支持**。
151
168
 
152
- ### Changed
169
+ ### 变更
153
170
 
154
- - **Outbound text path:** `process-message` uses `StreamingMarkdownFilter` (`feed` / `flush`) per deliver chunk instead of `markdownToPlainText`.
171
+ - **外发文本:** `process-message` 在每次 `deliver` 时用 `StreamingMarkdownFilter`(`feed` / `flush`)处理回复,替代 `markdownToPlainText`。
155
172
 
156
- ### Removed
173
+ ### 移除
157
174
 
158
- - **`markdownToPlainText`** from `src/messaging/send.ts` (and its tests from `send.test.ts`); coverage moves to `markdown-filter.test.ts`.
175
+ - 从 `src/messaging/send.ts` 删除 **`markdownToPlainText`**(相关用例从 `send.test.ts` 迁至 `markdown-filter.test.ts`)。
159
176
 
160
177
  ## [2.1.2] - 2026-04-02
161
178
 
162
- ### Changed
179
+ ### 变更
163
180
 
164
- - **Config reload after login:** On each successful Weixin login, bump `channels.openclaw-weixin.channelConfigUpdatedAt` (ISO 8601) in `openclaw.json` so the gateway reloads config from disk, instead of writing an empty `accounts: {}` placeholder.
165
- - **QR login:** Increase client timeout for `get_bot_qrcode` from 5s to 10s.
166
- - **Docs:** Uninstall instructions now use `openclaw plugins uninstall @tencent-weixin/openclaw-weixin` (aligned with the plugins CLI).
167
- - **Logging:** `debug-check` log line no longer includes `stateDir` / `OPENCLAW_STATE_DIR`.
181
+ - **登录后配置刷新:** 每次微信登录成功后,在 `openclaw.json` 中更新 `channels.openclaw-weixin.channelConfigUpdatedAt`(ISO 8601),让网关从磁盘重新加载配置;不再写入空的 `accounts: {}` 占位。
182
+ - **扫码登录:** `get_bot_qrcode` 客户端超时由 5s 调整为 10s。
183
+ - **文档:** 卸载说明改为使用 `openclaw plugins uninstall @tencent-weixin/openclaw-weixin`,与插件 CLI 一致。
184
+ - **日志:** `debug-check` 日志不再输出 `stateDir` / `OPENCLAW_STATE_DIR`。
168
185
 
169
- ### Removed
186
+ ### 移除
170
187
 
171
- - **`openclaw-weixin` CLI subcommands** (`src/weixin-cli.ts` and registration in `index.ts`). Use the host `openclaw plugins uninstall …` flow instead.
188
+ - **`openclaw-weixin` 子命令**(删除 `src/weixin-cli.ts` 及 `index.ts` 中的注册)。请使用宿主自带的 `openclaw plugins uninstall …` 卸载流程。
172
189
 
173
- ### Fixed
190
+ ### 修复
174
191
 
175
- - Resolves the **dangerous code pattern** warning when installing the plugin on **OpenClaw 2026.3.31+** (host plugin install / static checks).
192
+ - 解决在 **OpenClaw 2026.3.31 及更新版本**上安装插件时出现的 **dangerous code pattern** 提示(宿主插件安装 / 静态检查)。
@@ -1,171 +1,3 @@
1
- # 变更日志
1
+ # openclaw-weixin
2
2
 
3
- [English](CHANGELOG.md)
4
-
5
- 本项目遵循 [Keep a Changelog](https://keepachangelog.com/) 格式。
6
-
7
- ## [未发布]
8
-
9
- ### 变更
10
-
11
- - 将最低支持的 OpenClaw 宿主提升至 `2026.7.1`,并使运行时检查、包元数据、
12
- 开发环境及 CI 的 Node.js 最低版本与该版本保持一致。
13
-
14
- ### 安全
15
-
16
- - 将存在漏洞的开发期传递依赖覆盖为已修复版本,并在 CI 与 npm 发布流程中
17
- 增加中危及以上依赖审计门禁。
18
-
19
- ## [2.4.6] - 2026-07-23
20
-
21
- ### 变更
22
-
23
- - 基于腾讯 `@tencent-weixin/openclaw-weixin` 准备首个社区维护的未加 scope
24
- npm 发行包 `openclaw-weixin`。
25
- - 保留内部 `openclaw-weixin` 插件/channel ID、配置键与状态目录,支持原位
26
- 切换。
27
- - 增加社区仓库元数据、包内容检查和 npm Trusted Publishing 工作流。
28
- - 将运行时兼容检查与文档统一为 OpenClaw `>=2026.5.12`、Node.js `>=22`。
29
-
30
- ## [2.4.5] - 2026-06-22
31
-
32
- ### 新增
33
-
34
- - **`classifyFetchError` — 网络错误分类:** `src/api/api.ts` 新增 `classifyFetchError` 工具函数,将 fetch 级错误分类为 `dns` / `tcp` / `tls` / `timeout` / `unknown`。`apiGetFetch` 与 `apiPostFetch` 在失败时输出结构化日志(type, description, code),便于排查网络问题。覆盖 ENOTFOUND、ECONNREFUSED、ETIMEDOUT、SSL/TLS、AbortError 等场景的完整测试。
35
- - **`sendMessage` 返回值校验:** `sendMessage` 现在解析服务端返回的 `SendMessageResp`(`ret` / `errmsg`),`ret` 非零时抛错,避免消息发送静默失败。
36
-
37
- ### 变更
38
-
39
- - **`SESSION_EXPIRED_ERRCODE` → `STALE_TOKEN_ERRCODE`:** 在 `src/api/session-guard.ts` 中重命名,更准确地描述 token 过期(-14 表示 token 失效,而非 session 过期)。`monitor.ts` 与测试中所有引用同步更新。
40
- - **错误日志改进:**
41
- - `monitor.ts` 中 `getUpdates` 的错误日志使用 `classifyFetchError` 输出分类信息(type, description, code)。
42
- - `monitor.ts` 移除重复的 `errLog` 日志行,仅保留 `aLog.error`。
43
- - CDN 上传失败日志(`cdn-upload.ts`)增加脱敏 URL 和错误 cause 信息。
44
- - `downloadRemoteImageToTemp`(`upload.ts`)增加 fetch 网络错误详情日志。
45
- - API GET/POST fetch 失败日志(`api.ts`)增加脱敏 URL、超时设置及错误分类信息。
46
- - **最低宿主版本升级:** `peerDependencies.openclaw` 和 `install.minHostVersion` 从 `>=2026.3.22` 升至 `>=2026.5.12`。
47
-
48
- ### 新增(开发/工程)
49
-
50
- - **`outbound-hooks.test.ts`:** 新增测试文件,覆盖 `applyWeixinMessageSendingHook`(无 hook、内容修改、取消、错误容错)和 `emitWeixinMessageSent`(无 hook、成功、失败走 fire-and-forget)各场景。
51
-
52
- ### 修复
53
-
54
- - **`pairing.test.ts` mock 路径:** `vi.mock` 目标从 `"openclaw/plugin-sdk"` 修正为 `"openclaw/plugin-sdk/infra-runtime"`。
55
- - **`api.test.ts` sendMessage 测试 mock:** 成功用例的 mock 返回值从 `""` 改为 `"{}"`,与 `sendMessage` 新增的响应解析逻辑一致。
56
-
57
- ## [2.4.4] - 2026-05-22
58
-
59
- ### 新增
60
-
61
- - **工具调用进度消息:** 模型执行 tool 时,发送 `TOOL_CALL_START` / `TOOL_CALL_RESULT` 进度消息,可通过 `replyProgressMessages` 开关控制(默认开启)。
62
- - **请求中断信号支持:** `apiPostFetch` / `getUpdates` 现在接受外部的 `AbortSignal`。当网关停止或热重载频道时,正在进行的 long-poll 请求会被立即取消,无需等待服务端超时。
63
-
64
- ## [2.4.3] - 2026-05-08
65
-
66
- ### 修复
67
-
68
- - **`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 容错继续向上查找。
69
- - **`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 退出。
70
-
71
- ## [2.4.2] - 2026-05-07
72
-
73
- ### 修复
74
-
75
- - **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 下的网络调用。
76
- - **OpenClaw ≥ 2026.5.x——微信 runtime 初始化超时无限重启。** 移除模块作用域的 `pluginRuntime` 全局变量(同时删掉 `src/runtime.ts`),改为按调用从网关 ctx 中读取 `ctx.channelRuntime`。原先的全局是在插件注册阶段写入的,但较新宿主改为按调用注入 runtime surface,启动时拿不到/拿到旧值,channel 启动一直超时进而被反复重启。
77
-
78
- ### 移除
79
-
80
- - **冗余脚本与入口:** 删除调试用的 `scripts/test-full-upload.ts` / `scripts/test-upload-url.ts`,以及遗留的 `index.ts` 转发文件。对调用方无行为变更。
81
-
82
- ## [2.4.1] - 2026-05-04
83
-
84
- ### 新增
85
-
86
- - **npm 包内携带 dist 产物作为 channel 入口:** `package.json` 的 `files` 加入 `dist/`,`openclaw.runtimeExtensions` 设为 `["./dist/index.js"]`;宿主直接加载预编译的 JS 入口,不再依赖装包时的 TypeScript 源码,避免在较严格的宿主版本上出现 `requires compiled runtime output for TypeScript entry index.ts` 错误。
87
- - **`openclaw.plugin.json` 频道配置:** 在 `openclaw.plugin.json` 中声明 `channels` 与 `channelConfigs`,使较新宿主(≥ 2026.4.x)能直接渲染频道选择 UI,无需回退到 `package.json#openclaw`。
88
-
89
- ## [2.3.1] - 2026-04-28
90
-
91
- ### 新增
92
-
93
- - **`bot_agent` 请求字段:** 上行 CGI 现在携带由上层应用提供的 `bot_agent`(类似 UA 的 `name/version (comment)` 语法,支持多个 product),按上层应用的 channel 配置传入;`src/api/api.ts` 中的 `sanitizeBotAgent` 负责清洗与长度上限,缺失或不合法时回落为 `OpenClaw`。
94
- - **扫码时上送 `local_token_list`:** `fetchQRCode` 现在带上本地最近 10 个 `bot_token`,让服务端识别"已绑定到本端"的 bot 并下发 `binded_redirect`,避免重复发会话。
95
- - **配对码登录流程:** 服务端要求二次校验时(`need_verifycode` / `verify_code_blocked`),`waitForWeixinLogin` 通过 stdin 提示用户输入 `verify_code` 并做有限次重试。
96
- - **`binded_redirect` 处理:** QR 轮询新增分支,输出 `✅ 已连接过此 OpenClaw,无需重复连接。` 并优雅返回。
97
- - **连接状态通知(start/stop):** `gateway.startAccount` 在 provider 注册后调用 `notifyStart`,新增的 `gateway.stopAccount` hook 调用 `notifyStop`,便于上游微信服务端对账户在线状态进行对账。
98
-
99
- ### 变更
100
-
101
- - **扫码登录文案:** 调整 QR / 扫码相关的提示文案;同时移除 `fetchQRCode` / `startWeixinLoginWithQr` 的客户端超时,长轮询仅受服务端与网络栈限制。
102
-
103
- ## [2.1.10] - 2026-04-24
104
-
105
- ### 新增
106
-
107
- - **连接状态通知(start/stop)首次引入:** 账号启动时发送 `notifyStart`,关闭时通过新的 `gateway.stopAccount` hook 发送 `notifyStop`。该能力在后续 2.3.x 中保留。
108
-
109
- ## [2.1.9] - 2026-04-20
110
-
111
- ### 新增
112
-
113
- - **外发 hook 支持:** 为所有外发路径(`sendText`、`sendMedia`、`process-message` 中的入站回复 `deliver`)接入 `message_sending`(发送前拦截/修改)和 `message_sent`(发送后通知)hook。hook 逻辑抽取至共享模块 `src/messaging/outbound-hooks.ts`。
114
-
115
- ### 变更
116
-
117
- - **清理:** 移除 `sendWeixinOutbound` 签名中未使用的 `mediaUrl` 参数。
118
-
119
- ## [2.1.8] - 2026-04-07
120
-
121
- ### 变更
122
-
123
- - **Markdown 过滤器:** `StreamingMarkdownFilter` 放开了更多 Markdown 格式的保留。
124
-
125
- ## [2.1.7] - 2026-04-07
126
-
127
- ### 修复
128
-
129
- - **插件注册重入:** `channel.ts` 中将 `monitorWeixinProvider` 改为在 `startAccount` 内部懒加载(`await import(...)`),避免插件注册阶段提前拉取 monitor → process-message → command-auth 依赖链,导致 plugin/provider registry 重入。
130
- - **初始化副作用:** `process-message.ts` 中将 `resolveSenderCommandAuthorizationWithRuntime` / `resolveDirectDmAuthorizationOutcome` 改为懒加载,避免模块初始化时触发宿主的 `ensureContextWindowCacheLoaded` 副作用,进而导致 `loadOpenClawPlugins` 重入。
131
-
132
- ### 变更
133
-
134
- - **tool-call 外发路径:** `sendWeixinOutbound` 现在对发送文本应用 `StreamingMarkdownFilter`,与 `process-message` 中的 model-output 路径保持一致。
135
-
136
- ## [2.1.4] - 2026-04-03
137
-
138
- ### 变更
139
-
140
- - **扫码登录:** 移除 `get_bot_qrcode` 的客户端超时,请求不再因固定时限被 abort(仍受服务端与网络栈限制)。
141
-
142
- ## [2.1.3] - 2026-04-02
143
-
144
- ### 新增
145
-
146
- - **`StreamingMarkdownFilter`**(`src/messaging/markdown-filter.ts`):外发文本由原先 `markdownToPlainText` 整段剥离 Markdown,改为流式逐字符过滤;**对 Markdown 从完全不支持变为部分支持**。
147
-
148
- ### 变更
149
-
150
- - **外发文本:** `process-message` 在每次 `deliver` 时用 `StreamingMarkdownFilter`(`feed` / `flush`)处理回复,替代 `markdownToPlainText`。
151
-
152
- ### 移除
153
-
154
- - 从 `src/messaging/send.ts` 删除 **`markdownToPlainText`**(相关用例从 `send.test.ts` 迁至 `markdown-filter.test.ts`)。
155
-
156
- ## [2.1.2] - 2026-04-02
157
-
158
- ### 变更
159
-
160
- - **登录后配置刷新:** 每次微信登录成功后,在 `openclaw.json` 中更新 `channels.openclaw-weixin.channelConfigUpdatedAt`(ISO 8601),让网关从磁盘重新加载配置;不再写入空的 `accounts: {}` 占位。
161
- - **扫码登录:** `get_bot_qrcode` 客户端超时由 5s 调整为 10s。
162
- - **文档:** 卸载说明改为使用 `openclaw plugins uninstall @tencent-weixin/openclaw-weixin`,与插件 CLI 一致。
163
- - **日志:** `debug-check` 日志不再输出 `stateDir` / `OPENCLAW_STATE_DIR`。
164
-
165
- ### 移除
166
-
167
- - **`openclaw-weixin` 子命令**(删除 `src/weixin-cli.ts` 及 `index.ts` 中的注册)。请使用宿主自带的 `openclaw plugins uninstall …` 卸载流程。
168
-
169
- ### 修复
170
-
171
- - 解决在 **OpenClaw 2026.3.31 及更新版本**上安装插件时出现的 **dangerous code pattern** 提示(宿主插件安装 / 静态检查)。
3
+ 中文变更日志已移至 [CHANGELOG.md](./CHANGELOG.md)。