Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@

This project follows the [Keep a Changelog](https://keepachangelog.com/) format.

## [Unreleased]

### Added

- **Quote reconstruction for newer WeChat clients:** Losslessly parse message IDs and resolve ID-only `svr_id` text and partial quotes through a per-account, per-conversation SQLite side store. Images, video, voice, and attachments are written directly into plugin-owned OpenClaw managed storage, using one retained file with time, count, byte-budget, and single-file eviction limits. Restored attachments include tool-access hints so agents can locate and read the file when automatic extraction fails.
- **Compatible degradation:** Disable quote caching when `node:sqlite` is unavailable or `quoteCache.enabled=false`, with no in-memory fallback. Cache failures never interrupt normal message delivery.

## [2.4.7] - 2026-08-31

### Fixed
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@

本项目遵循 [Keep a Changelog](https://keepachangelog.com/) 格式。

## [未发布]

### 新增

- **新版微信引用消息还原:** 对消息 ID 做无损解析,并用按账号、会话隔离的 SQLite 旁路存储还原只携带 `svr_id` 的文本引用和局部引用。图片、视频、语音及附件首次直接写入插件专属的 OpenClaw 受管目录,以单份文件支持按时间、条数、空间和单文件大小淘汰;还原引用附件时会提供工具访问提示,便于 agent 在自动抽取失败后定位并读取文件。
- **兼容降级:** `node:sqlite` 不可用或 `quoteCache.enabled=false` 时关闭引用缓存,不启用内存替代方案;缓存异常不会影响正常消息收发。

## [2.4.7] - 2026-08-31

### 修复
Expand Down
42 changes: 39 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ OpenClaw's Weixin channel plugin. Connect an OpenClaw Gateway to Weixin with QR-

| Component | Requirement |
| --- | --- |
| Node.js | `>=22` |
| Node.js | `>=22.13.0` |
| OpenClaw runtime check | `>=2026.3.22` |
| npm peer dependency | `>=2026.5.12` |

Expand Down Expand Up @@ -100,6 +100,39 @@ Set an optional identifier for backend log attribution and monitoring:

`botAgent` is used for observability only. It is not an authentication credential and does not control message routing.

**Format** (UA-style):

- One or more `Name/Version` tokens, space-separated
- Each token may optionally be followed by ` (comment)`
- ASCII only; total length ≤ 256 bytes
- Invalid tokens are silently dropped during sanitization; falls back to
`OpenClaw` if nothing valid remains

Examples that pass through unchanged:

- `MyBot/1.2.0`
- `MyBot/1.2.0 (region=cn;env=prod)`
- `MyBot/1.2.0 LangChain/0.3.5`
- `MyBot/1.2.0-rc.1+build.5`

**Note**: `bot_agent` is for observability only — it is not used for
authentication or routing. All registered agents on this plugin instance
currently share the same `botAgent` declaration; per-agent overrides may be
added in a future version if needed.

## Local quote cache

Newer WeChat clients may send only a server message ID for a quoted message. The plugin
stores the required text and media metadata locally so later quotes can restore their
context. The cache is enabled by default and failures do not interrupt normal message
delivery.

Configure it under `channels.openclaw-weixin.quoteCache` when you need different
retention or size limits. The default limits are 30 days and 10,000 text records per
account, plus 7 days, 256 MiB per account, and 25 MiB per media file. See the
[local quote cache guide](./docs/quote-cache_zh_CN.md) for the complete configuration,
storage behavior, and validation details.

## Uninstall

```bash
Expand Down Expand Up @@ -135,17 +168,18 @@ If the problem persists, inspect the Gateway log and verify that the account has
| --- | --- |
| Backend integration | [Weixin backend API protocol](./docs/protocol.md) |
| CI and local quality checks | [CI guide](./docs/ci.md) |
| Development and local validation | [Development guide](./docs/development.md) |
| OpenClaw channel configuration | [OpenClaw channels](https://docs.openclaw.ai/channels) |
| Release history | [CHANGELOG.md](./CHANGELOG.md) |

The backend protocol document is intended for developers implementing or integrating a compatible backend. It is not required for normal plugin installation.

## Development

This repository uses npm and requires Node.js `>=22`.
This repository uses npm and requires Node.js `>=22.13.0`.

```bash
npm ci --ignore-scripts
npm ci --ignore-scripts --include=dev
npm run ci
```

Expand All @@ -157,6 +191,8 @@ npm run test:coverage

Pull requests run the same quality, unit-test, coverage, build, and package smoke checks in GitHub Actions. See the [CI guide](./docs/ci.md) for details.

See the [development guide](./docs/development.md) for the complete worktree, dependency, packaging, and local installation workflow.

## Contributing

Bug reports, documentation improvements, tests, and code contributions are welcome. Please keep pull requests focused and include validation details. For changes to the backend integration, update the [protocol documentation](./docs/protocol.md) together with the implementation.
Expand Down
34 changes: 32 additions & 2 deletions README.zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ OpenClaw 的微信渠道插件。通过扫码登录将 OpenClaw Gateway 连接

| 组件 | 要求 |
| --- | --- |
| Node.js | `>=22` |
| Node.js | `>=22.13.0` |
| OpenClaw 运行时检查 | `>=2026.3.22` |
| npm peer dependency | `>=2026.5.12` |

Expand Down Expand Up @@ -100,6 +100,33 @@ openclaw config set session.dmScope per-account-channel-peer

`botAgent` 仅用于观测,不是鉴权凭证,也不控制消息路由。

**格式规范**(UA 风格):

- 一个或多个 `Name/Version` token,空格分隔
- 每个 token 可选地跟一个 ` (comment)`
- 仅允许 ASCII 字符;总长 ≤ 256 字节
- 不合规的 token 在清洗时静默丢弃;如果最终为空,回退到 `OpenClaw`

可直接使用的示例:

- `MyBot/1.2.0`
- `MyBot/1.2.0 (region=cn;env=prod)`
- `MyBot/1.2.0 LangChain/0.3.5`
- `MyBot/1.2.0-rc.1+build.5`

**注意**:`bot_agent` 仅用于观测,**不参与鉴权或路由**。当前本插件实例下所有
已注册的 agent 共享同一个 `botAgent` 声明;如有需要按 agent 单独标识的场景,
可在后续版本扩展配置。

## 引用消息本地缓存

新版微信客户端可能只在引用消息中提供服务端消息 ID。插件会在本地保存必要的文本和媒体元数据,
以便后续引用消息还原上下文。缓存默认开启,缓存故障不会中断正常消息收发。

如需调整保留时间或空间限制,可配置 `channels.openclaw-weixin.quoteCache`。默认文本缓存保留 30 天、
每个账号最多 10,000 条;媒体缓存保留 7 天、每个账号最多 256 MiB、单个文件最多 25 MiB。
完整配置、存储行为和验证说明见[引用消息本地缓存开发说明](./docs/quote-cache_zh_CN.md)。

## 卸载

```bash
Expand Down Expand Up @@ -135,14 +162,15 @@ openclaw gateway restart
| --- | --- |
| 后端对接 | [微信后端 API 协议](./docs/protocol_zh_CN.md) |
| CI 和本地质量检查 | [CI 指南](./docs/ci_zh_CN.md) |
| 开发与本地验证 | [开发者指南](./docs/development_zh_CN.md) |
| OpenClaw 渠道配置 | [OpenClaw Channels](https://docs.openclaw.ai/channels) |
| 发布历史 | [CHANGELOG.zh_CN.md](./CHANGELOG.zh_CN.md) |

后端协议文档面向实现或对接兼容后端的开发者,普通用户安装插件时不需要阅读。

## 开发

本项目使用 npm,并要求 Node.js `>=22`。
本项目使用 npm,并要求 Node.js `>=22.13.0`。

```bash
npm ci --ignore-scripts
Expand All @@ -157,6 +185,8 @@ npm run test:coverage

Pull Request 会在 GitHub Actions 中执行质量检查、单元测试、覆盖率、构建和 npm 包冒烟测试。详细说明见 [CI 指南](./docs/ci_zh_CN.md)。

从 worktree 创建、依赖安装到本地打包和插件安装的完整流程见[开发者指南](./docs/development_zh_CN.md)。

## 参与贡献

欢迎提交问题、改进文档、补充测试和贡献代码。请保持 Pull Request 聚焦,并附上验证结果。修改后端集成时,请同步更新[协议文档](./docs/protocol_zh_CN.md)。
Expand Down
2 changes: 1 addition & 1 deletion docs/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This document describes the local quality checks and GitHub Actions workflow for

## Local checks

The project requires Node.js `>=22`. After cloning the repository or changing dependencies, install the locked dependencies first:
The project requires Node.js `>=22.13.0`. After cloning the repository or changing dependencies, install the locked dependencies first:

```bash
npm ci --ignore-scripts
Expand Down
2 changes: 1 addition & 1 deletion docs/ci_zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## 本地检查

项目要求 Node.js `>=22`。首次获取代码或依赖发生变化后,先安装 lockfile 中锁定的依赖:
项目要求 Node.js `>=22.13.0`。首次获取代码或依赖发生变化后,先安装 lockfile 中锁定的依赖:

```bash
npm ci --ignore-scripts
Expand Down
160 changes: 160 additions & 0 deletions docs/development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Development and Local Validation

This guide describes the common workflow for developing, testing, and locally validating this project.

## Prerequisites

Make sure Node.js, npm, Git, and OpenClaw are installed:

```bash
node --version
npm --version
git --version
openclaw --version
```

The required Node.js version is defined by the `engines` field in `package.json`.

## Create a worktree

Use a separate worktree for an independent feature or pull request:

```bash
PR_NUMBER=123 # replace with the actual pull request number
WORKTREE_DIR="/tmp/openclaw-weixin-pr-${PR_NUMBER}"
REVIEW_BRANCH="review/pr-${PR_NUMBER}"

git fetch origin main
git fetch origin "+refs/pull/${PR_NUMBER}/head:refs/remotes/origin/pr-${PR_NUMBER}"
git worktree add -b "$REVIEW_BRANCH" "$WORKTREE_DIR" origin/main
cd "$WORKTREE_DIR"
git merge --no-ff "origin/pr-${PR_NUMBER}"
```

Check the current worktree and branch:

```bash
git branch --show-current
git status
```

## Resolve merge conflicts

List conflicted files:

```bash
git status
git diff --name-only --diff-filter=U
```

Edit the files, keep the correct content, and remove the `<<<<<<<`, `=======`, and `>>>>>>>` markers. Then finish the merge:

```bash
git add <resolved files>
git commit -m "resolve merge conflicts"
git diff --check
```

To synchronize with a newer main branch:

```bash
git fetch origin main
git merge origin/main
```

## Install dependencies

Run the command from the project root, where `package.json` and `package-lock.json` are located:

```bash
npm ci --ignore-scripts --include=dev
```

`npm ci` installs the versions recorded in the lockfile and is suitable for clean, reproducible validation.

When changing dependencies, use `npm install`, commit both dependency files, and run `npm ci` again:

```bash
npm install --save-dev --save-exact <package>@<version>
npm ci --ignore-scripts --include=dev
```

Installation warnings do not necessarily mean that installation failed. Check the command exit code and final result. Do not run `npm audit fix --force` without reviewing the changes it would make.

## Run quality checks

Run the complete check:

```bash
npm run ci
```

This runs formatting, linting, type checking, unit tests, and the build. To run them separately:

```bash
npm run format:check
npm run lint
npm run typecheck
npm run test:unit
npm run build
```

Run coverage separately when needed:

```bash
npm run test:coverage
```

## Pack the local plugin

Build from the project root, then create a local npm package:

```bash
npm run build

PACKAGE_DIR=$(mktemp -d /tmp/openclaw-weixin-package.XXXXXX)
npm pack --pack-destination "$PACKAGE_DIR"

PACKAGE_TGZ=$(find "$PACKAGE_DIR" \
-maxdepth 1 \
-type f \
-name '*.tgz' \
-print \
-quit)

echo "$PACKAGE_TGZ"
test -n "$PACKAGE_TGZ" || { echo "Package not found"; exit 1; }
```

`PACKAGE_DIR` is the temporary directory. `PACKAGE_TGZ` is the `.tgz` file generated inside it and must be passed to the installer.

## Install and validate the local package

```bash
openclaw plugins install "$PACKAGE_TGZ" \
--force \
--accept-capabilities

openclaw gateway restart
openclaw channels status
```

Perform manual checks relevant to the change, such as login, message delivery, media handling, configuration, restart behavior, and failure fallback.

To avoid changing an existing OpenClaw configuration, use a separate `OPENCLAW_STATE_DIR` during validation.

## Common issues

- `uv_cwd` or `process.cwd`: the current directory was deleted, often because the shell was inside `dist` while the build cleaned it. Change back to the project root.
- `Plugin install source must not be empty`: `PACKAGE_TGZ` is unset or empty. Run the packaging commands again.
- `HOOK.md missing`: the temporary `PACKAGE_DIR` directory was passed to the installer instead of the `PACKAGE_TGZ` archive.

## Before committing

```bash
git status
git diff --check
npm run ci
```

Review the code, tests, and documentation before committing. Use the repository's established release process for versioning and publish packages separately after the change is merged.
Loading
Loading