# dist/ — release artifacts ## v2.0 三件套(当前推荐) | 文件 | 作用 | 装法 | |---|---|---| | `fmode-openclaw-wechat-agent-0.1.4.tgz` | Channel plugin(常驻 gateway,inbound 自动回复)| `openclaw plugins install ./fmode-openclaw-wechat-agent-0.1.4.tgz && systemctl --user restart openclaw-gateway.service` | | `fmode-wechat-cli-0.1.3.tgz` | `wecli` CLI(out-of-band 微信操作,被 skill 按需调用) | `tar -xzf fmode-wechat-cli-0.1.3.tgz && cd package && npm link` _(或参考工作区根 README 的 `~/.local/bin/` 单文件部署)_ | | `wechat.SKILL.md` | OpenClaw skill 文件,教 LLM 何时 / 如何用 `wecli` | `mkdir -p ~/.openclaw/skills/wechat && cp wechat.SKILL.md ~/.openclaw/skills/wechat/SKILL.md && systemctl --user restart openclaw-gateway.service` | 三件共用同一个 `apiBase`(`http://8.138.37.248/api/wechat-agent`),**职责正交**: - 有人 DM bot → channel 自动回 → **不要**让 skill 也发一次 - 用户让 agent 主动操作微信(搜联系人/查历史/发给第三方)→ agent 调 skill → skill 告诉 LLM 跑 `wecli ` ## v1.x 历史归档(可选,新部署不要用) | 文件 | 说明 | |---|---| | `openclaw-wechat-skill-v1.0.0.zip` ~ `v1.2.2.zip` | v1.x skill 包 + daemon,已被 v2.0 三件套替代 | 如果老客户机上还跑着 v1.x 并装了 channel plugin 0.1.1,建议走 `channel-plugin/README.md` 的 **Upgrading / re-installing** 段的 jq 备份 + 移走老 `~/.openclaw/skills/wechat-*` 流程(详见工作区根 README 和 `docs/channel-plugin-design.md`)。 ## 版本记录 - **2026-04-28** v0.1.4 channel plugin + v0.1.3 CLI — **多设备 appId 隔离**。后端新增多设备注册表后,channel plugin 和 CLI 同步适配: - `openclaw.plugin.json` configSchema 新增 `appId` 字段,可在 OpenClaw Control 网页或 `openclaw.json` 里配置。 - `createClient(apiBase, appId)` 自动把 `appId` 注入所有 POST body 和 GET query,消息、会话、联系人均按设备隔离。 - `monitor.ts` 从 `channelCfg.appId` 读取并传递给 client,启动日志打印 `appId=`。 - CLI 新增 `--app-id` 全局 flag + `WECHAT_APP_ID` 环境变量 + `~/.wecli/config.json` 中 `appId` 字段,三级优先。 - `SKILL.md` Requirements 段补充多设备配置说明。 - 单设备部署无需任何改动(appId 不填则使用后端默认设备)。 - **2026-04-22** v0.1.3 channel plugin — **真正修好** crash-loop。0.1.2 删 `timer.unref()` 没够 —— 客户机装完 0.1.2 后仍每 10-90s 看到 `[wechat-agent] starting poller` + 4 ms 后 `[default] auto-restart attempt N/10 in Xs`。读 `node_modules/openclaw/dist/server.impl-*.js` 才发现 OpenClaw gateway supervisor 把 `startAccount(ctx)` 返回的 Promise **本身**当 channel lifecycle task: ```js runTask().finally(() => runtime.running = false) .then(() => autoRestart(attempt, backoff)); ``` 我们之前 `return startMonitor(...)` 在 ~10ms 内就 resolve 成 `{shutdown}` 句柄 → supervisor 立即置 `running: false` → 排 auto-restart。修法:`startAccount` 里 `await new Promise(resolve => ctx.abortSignal.addEventListener("abort", resolve, {once: true}))` 挂住,只有 OpenClaw 主动 abort(stopAccount / config reload / gateway shutdown)才 resolve,然后再 `await monitor.shutdown()` 收尾。 - **2026-04-22** v0.1.2 channel plugin(**已被 0.1.3 替代,不要再用**)— 删 `monitor.ts:227` 的 `timer.unref()` 和 `cooldown.ts:119` 的 `dispatchTimer.unref()`。这两处改是对的(保留在 0.1.3 里),但当时以为这就是 crash-loop 根因,实际是 lifecycle contract 问题。 - **2026-04-22** v0.1.2 CLI — 修 `contacts search` 和 `contacts list`: 1. `/contacts/search` 后端其实是 GEWE 的 **exact wxid/手机号/微信号** 精确查询(给"添加陌生人"用的),**不**是模糊名字搜索,传 `keyword=zleo` 会 HTTP 400 `Missing required field: contactsInfo`。改用 `/conversations` 当主要搜索源(含 wxid + nickName 对),`/contacts/list` 按 wxid 子串兜底。 2. `/contacts/list[-cache]` 响应形状其实是 `{data: {friends:[wxid...], chatrooms:[...], ghs:[gh_...]}}`(**字符串数组**分组),不是 `[Contact,...]`。旧代码按 `data=array` 或 `{list:[...]}` 解析 → 永远返 0 条。现在展平成 `{wxid, type}`。 - **2026-04-22** v0.1.1 CLI — 修 EPIPE bug(`wecli ... | head -N` 这类下游提前关管道的场景会让 Node 以 Unhandled 'error' event 崩溃。patch 给 `process.stdout/stderr` 挂 EPIPE → clean exit 0 的听器)。已被 0.1.2 替换。 - **2026-04-22** v0.1.0 CLI + wechat skill 首次发布;0.1.1 channel plugin 同步归档。_(0.1.0 已删 — EPIPE bug。)_ - **2026-04-21** v0.1.1 channel plugin(esbuild 单文件 bundle,消除 `Cannot find package 'openclaw'`),已在客户 Linux 机验收通过。 - **2026-04-18** v1.2.2 daemon(最后一个 v1.x 版本)。