@unlinearity/cli-wechat-bridge 1.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/LICENSE.txt +21 -0
- package/README.md +531 -0
- package/bin/_run-entry.mjs +41 -0
- package/bin/wechat-bridge-claude.mjs +5 -0
- package/bin/wechat-bridge-codex.mjs +5 -0
- package/bin/wechat-bridge-opencode.mjs +5 -0
- package/bin/wechat-bridge-shell.mjs +5 -0
- package/bin/wechat-bridge.mjs +5 -0
- package/bin/wechat-check-update.mjs +5 -0
- package/bin/wechat-claude-start.mjs +5 -0
- package/bin/wechat-claude.mjs +5 -0
- package/bin/wechat-codex-start.mjs +5 -0
- package/bin/wechat-codex.mjs +5 -0
- package/bin/wechat-opencode-start.mjs +5 -0
- package/bin/wechat-opencode.mjs +5 -0
- package/package.json +86 -0
- package/src/bridge/bridge-adapters.claude.ts +1047 -0
- package/src/bridge/bridge-adapters.codex.ts +2733 -0
- package/src/bridge/bridge-adapters.core.ts +877 -0
- package/src/bridge/bridge-adapters.opencode.ts +2390 -0
- package/src/bridge/bridge-adapters.shared.ts +1647 -0
- package/src/bridge/bridge-adapters.shell.ts +456 -0
- package/src/bridge/bridge-adapters.ts +30 -0
- package/src/bridge/bridge-controller.ts +58 -0
- package/src/bridge/bridge-final-reply.ts +56 -0
- package/src/bridge/bridge-process-reaper.ts +417 -0
- package/src/bridge/bridge-state.ts +520 -0
- package/src/bridge/bridge-types.ts +218 -0
- package/src/bridge/bridge-utils.ts +1524 -0
- package/src/bridge/claude-hook.ts +92 -0
- package/src/bridge/claude-hooks.ts +376 -0
- package/src/bridge/wechat-bridge.ts +1305 -0
- package/src/commands/check-update.ts +46 -0
- package/src/companion/codex-panel-link.ts +151 -0
- package/src/companion/codex-panel.ts +225 -0
- package/src/companion/codex-remote-client.ts +178 -0
- package/src/companion/local-companion-link.ts +338 -0
- package/src/companion/local-companion-start.ts +520 -0
- package/src/companion/local-companion.ts +532 -0
- package/src/media/media-types.ts +11 -0
- package/src/runtime/create-runtime-host.ts +16 -0
- package/src/runtime/legacy-adapter-runtime.ts +55 -0
- package/src/runtime/runtime-types.ts +51 -0
- package/src/utils/version-checker.ts +197 -0
- package/src/wechat/channel-config.ts +141 -0
- package/src/wechat/setup.ts +232 -0
- package/src/wechat/standalone-bot.ts +483 -0
- package/src/wechat/wechat-channel.ts +608 -0
- package/src/wechat/wechat-transport.ts +1290 -0
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 unlinearity
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,531 @@
|
|
|
1
|
+
# CLI WeChat Bridge
|
|
2
|
+
|
|
3
|
+
**命令行工具的微信桥接**:本项目用于桥接微信消息与本地运行的 [`Codex`](https://github.com/openai/codex)、[`Claude Code`](https://code.claude.com/docs/en/overview) 或持久化 `powershell.exe` 会话,并将本地输出、审批请求与运行状态同步回微信。
|
|
4
|
+
|
|
5
|
+
当前实现以本地工作流为中心展开,重点是保留本地原生终端体验,并在此基础上提供微信侧的远程输入、结果回流与状态同步能力。
|
|
6
|
+
|
|
7
|
+
## 这个项目解决什么问题
|
|
8
|
+
|
|
9
|
+
本项目面向这样一类使用场景:
|
|
10
|
+
|
|
11
|
+
- 你的主工作流仍在本地终端中进行
|
|
12
|
+
- 你希望继续使用原生 `codex` 或其他 CLI 工具,而不是迁移到网页或托管机器人
|
|
13
|
+
- 你希望在离开电脑时,仍能通过微信向本地会话发送请求,并接收必要的输出、与状态同步
|
|
14
|
+
|
|
15
|
+
当前项目并不试图把微信变成新的主工作界面。相反,它的定位是:
|
|
16
|
+
|
|
17
|
+
- 本地 CLI 仍然是主工作界面
|
|
18
|
+
- 微信是远程入口,允许远程接入
|
|
19
|
+
- 会话一致性、线程状态和审批流仍以**本地会话为中心**
|
|
20
|
+
|
|
21
|
+
## 快速开始
|
|
22
|
+
|
|
23
|
+
### 环境要求
|
|
24
|
+
|
|
25
|
+
- Windows 为当前主要验证环境
|
|
26
|
+
- [Node.js](https://nodejs.org/en/download) `>= 24.0.0`(建议直接安装官网 LTS 版本)
|
|
27
|
+
- [Bun](https://bun.sh/docs/installation) `>= 1.0.0`
|
|
28
|
+
- 已安装以下至少一种本地 CLI:(最好更新至最新版本)
|
|
29
|
+
- [Codex](https://github.com/openai/codex)
|
|
30
|
+
- [Claude Code](https://code.claude.com/docs/en/overview)
|
|
31
|
+
- powershell.exe
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### 1. 安装全局命令
|
|
35
|
+
|
|
36
|
+
正式版本可以直接从 npm 安装:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install -g @unlinearity/cli-wechat-bridge
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
安装后可在任意项目目录中直接使用 `wechat-codex-start`、`wechat-claude-start`、`wechat-opencode-start` 等命令。
|
|
43
|
+
|
|
44
|
+
如果你希望从源码运行或参与开发,也可以克隆仓库并安装依赖:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
git clone https://github.com/UNLINEARITY/CLI-WeChat-Bridge
|
|
48
|
+
cd CLI-WeChat-Bridge
|
|
49
|
+
bun install
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 2. 源码安装全局命令
|
|
53
|
+
|
|
54
|
+
如果使用源码仓库,希望将当前工作区安装为全局命令:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npm install -g . #将命令下载到全局
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
如果仓库更新,可以重新clone,而本地留有旧配置,再强制更新:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm install -g . --force # 强制清除旧配置
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
开发阶段也可以使用:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm link
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
说明:
|
|
73
|
+
|
|
74
|
+
- `npm link` 会让全局命令直接指向当前仓库源码
|
|
75
|
+
- `npm install -g .` 会安装一份当前仓库的复制版本;后续代码更新后需要重新执行一次
|
|
76
|
+
|
|
77
|
+
### 3. 完成微信登录
|
|
78
|
+
|
|
79
|
+
> 在 clone 的仓库目录下:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
bun run setup # 绑定微信 ClawBot
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
该流程会:
|
|
86
|
+
|
|
87
|
+
1. 获取微信登录二维码
|
|
88
|
+
2. 选择 y 确认,在终端打印二维码
|
|
89
|
+
3. 等待你在微信中扫码并确认
|
|
90
|
+
4. 将 bot 凭据写入本地数据目录
|
|
91
|
+
|
|
92
|
+

|
|
93
|
+
|
|
94
|
+
默认凭据文件路径:
|
|
95
|
+
|
|
96
|
+
```text
|
|
97
|
+
~/.claude/channels/wechat/account.json
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 4. 启动 `codex` 模式
|
|
101
|
+
|
|
102
|
+
假设你的项目目录是:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
cd D:\work\your-project
|
|
106
|
+
```
|
|
107
|
+
> 当你下载到全局`npm install -g .`后,可以在任意的路径运行桥接!
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
终端 A:(这是用于监听和服务的,先打开这个)
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
wechat-bridge-codex
|
|
114
|
+
```
|
|
115
|
+

|
|
116
|
+
|
|
117
|
+
终端 B:(再新开一个窗口,运行以下命令,近乎原生的codex,不过暂时没有实现远程请求确认,待完善)
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
wechat-codex
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+

|
|
124
|
+
|
|
125
|
+
然后即可:(允许双向交互!windows 和 linux 均实测成功)
|
|
126
|
+
|
|
127
|
+
- 在微信中发送普通文本
|
|
128
|
+
- 在本地 `wechat-codex` 中继续原生交互
|
|
129
|
+
- 在本地执行 `/resume` 切线程
|
|
130
|
+
- 让微信自动跟随当前本地线程
|
|
131
|
+
|
|
132
|
+

|
|
133
|
+
|
|
134
|
+

|
|
135
|
+
|
|
136
|
+
如果你希望用**单命令入口**快速启动,也可以直接使用:(仅需打开一个终端)
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
wechat-codex-start
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
它会自动完成以下动作:
|
|
143
|
+
|
|
144
|
+
1. 复用当前目录已运行的 `wechat-bridge-codex`
|
|
145
|
+
2. 如果 bridge 正在服务其他目录,则停止旧 bridge 并切换到当前目录
|
|
146
|
+
3. 等待当前目录对应的本地 companion endpoint 就绪
|
|
147
|
+
4. 打开可见的 `wechat-codex` 会话
|
|
148
|
+
|
|
149
|
+
`wechat-codex-start` 现在按**单活工作区切换器**工作:
|
|
150
|
+
|
|
151
|
+
- 同一时间只有一个项目与微信对话
|
|
152
|
+
- 在当前目录重复执行是幂等的
|
|
153
|
+
- 如果当前目录已经有可见 companion / panel 在运行,则不会重复打开第二个窗口
|
|
154
|
+
- 如果检测到可见端仍在但 worker 状态异常(如 `stopped` / `error`),会自动重启 bridge 再重新打开可见端
|
|
155
|
+
- 在其他目录执行会显式切换活动工作区
|
|
156
|
+
|
|
157
|
+
### 5. 启动 Claude Code (不走Channels)
|
|
158
|
+
|
|
159
|
+
与 Codex 类似的,
|
|
160
|
+
|
|
161
|
+
终端 A:(这是用于监听和服务的,先打开这个)
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
wechat-bridge-claude
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
终端 B:(再新开一个窗口,运行以下命令,近乎原生的claude code,并且支持通过微信完成远程审批确认)
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
wechat-claude
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
也支持单命令启动:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
wechat-claude-start
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
它会自动在当前目录拉起或复用 `wechat-bridge-claude`,等待 endpoint 就绪后打开可见的 `wechat-claude` companion。
|
|
180
|
+
|
|
181
|
+

|
|
182
|
+
|
|
183
|
+

|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
## 适配器支持情况
|
|
187
|
+
|
|
188
|
+
> 目前支持将本地文件传输至微信
|
|
189
|
+
|
|
190
|
+

|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
| 适配器 | 当前状态 | 说明 |
|
|
194
|
+
| --- | --- | --- |
|
|
195
|
+
| `codex` | 已接入 | 双终端模式;本地 panel 为线程权威;微信跟随本地线程 |
|
|
196
|
+
| `claude` | 已接入 | 当前采用 `wechat-bridge-claude` + `wechat-claude` 的双终端 companion 模式;会话切换、最终回复与审批元数据已按 Claude session 语义同步 |
|
|
197
|
+
| `shell` | 可用 | 持久 `powershell.exe` 会话;高风险命令支持审批 |
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
## 命令说明
|
|
201
|
+
|
|
202
|
+
### 推荐全局命令
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
wechat-bridge-codex # 开启 Codex 的桥接
|
|
206
|
+
wechat-codex # 打开 Codex (原生交互)
|
|
207
|
+
wechat-codex-start # 开启 Codex 的桥接的同时, 打开 Codex
|
|
208
|
+
wechat-bridge-claude # 开启 Claude Code 的桥接
|
|
209
|
+
wechat-claude # 打开 Claude Code (原生交互)
|
|
210
|
+
wechat-claude-start # 开启桥接的同时, 打开 Claude Code
|
|
211
|
+
wechat-bridge-shell # 终端桥接,headless 进程
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### 仓库内开发入口
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
bun run setup
|
|
218
|
+
bun run bridge:codex
|
|
219
|
+
bun run codex:panel
|
|
220
|
+
bun run codex:start
|
|
221
|
+
bun run bridge:claude
|
|
222
|
+
bun run claude:companion
|
|
223
|
+
bun run claude:start
|
|
224
|
+
bun run bridge:shell
|
|
225
|
+
bun run bridge:bun -- --adapter codex
|
|
226
|
+
bun run test
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Bridge CLI 参数
|
|
230
|
+
|
|
231
|
+
适用于:
|
|
232
|
+
|
|
233
|
+
- `wechat-bridge-codex`
|
|
234
|
+
- `wechat-bridge-claude`
|
|
235
|
+
- `wechat-bridge-shell`
|
|
236
|
+
|
|
237
|
+
示例:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
wechat-bridge-codex --cwd D:\work\my-project
|
|
241
|
+
wechat-bridge-claude --profile work
|
|
242
|
+
wechat-bridge-shell --cmd pwsh.exe
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
支持参数:
|
|
246
|
+
|
|
247
|
+
- `--cwd <path>`:指定工作目录
|
|
248
|
+
- `--cmd <executable>`:覆盖默认命令
|
|
249
|
+
- `--profile <name-or-path>`:向适配器传入 profile
|
|
250
|
+
|
|
251
|
+
### `wechat-codex-start` 参数
|
|
252
|
+
|
|
253
|
+
示例:
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
wechat-codex-start --cwd D:\work\my-project
|
|
257
|
+
wechat-codex-start --profile work
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
支持参数:
|
|
261
|
+
|
|
262
|
+
- `--cwd <path>`:显式指定 bridge / companion 对应的工作目录
|
|
263
|
+
- `--profile <name-or-path>`:转发给后台启动的 `wechat-bridge-codex`
|
|
264
|
+
- `--timeout-ms <ms>`:等待当前目录 endpoint 的最长时间,默认 `15000`
|
|
265
|
+
|
|
266
|
+
行为说明:
|
|
267
|
+
|
|
268
|
+
- 同目录重复执行:复用当前目录 bridge;如果可见 companion / panel 已经在线,则只提示当前工作区已激活,不会重复打开第二个窗口
|
|
269
|
+
- 同目录检测到可见端仍在但 worker 状态异常(如 `stopped` / `error`)时:会自动回收旧 bridge 并重新启动
|
|
270
|
+
- 不同目录执行:会停止旧目录的临时 bridge,并切换到新的活动工作区
|
|
271
|
+
- 关闭可见 companion / panel 后,后台 `companion_bound` bridge 会一起退出;异常断开时会保留短暂重连窗口
|
|
272
|
+
|
|
273
|
+
### `wechat-claude-start` 参数
|
|
274
|
+
|
|
275
|
+
示例:
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
wechat-claude-start --cwd D:\work\my-project
|
|
279
|
+
wechat-claude-start --profile work
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
支持参数:
|
|
283
|
+
|
|
284
|
+
- `--cwd <path>`:显式指定 bridge / companion 对应的工作目录
|
|
285
|
+
- `--profile <name-or-path>`:转发给后台启动的 `wechat-bridge-claude`
|
|
286
|
+
- `--timeout-ms <ms>`:等待当前目录 endpoint 的最长时间,默认 `15000`
|
|
287
|
+
|
|
288
|
+
## 微信侧支持的指令
|
|
289
|
+
|
|
290
|
+
| 指令 | 说明 |
|
|
291
|
+
| --- | --- |
|
|
292
|
+
| 普通文本 | 发送给当前活动会话 |
|
|
293
|
+
| `/status` | 查看 bridge 当前状态 |
|
|
294
|
+
| `/stop` | 中断当前任务 |
|
|
295
|
+
| `/reset` | 重建当前本地会话 |
|
|
296
|
+
|
|
297
|
+
## 工作区模型
|
|
298
|
+
|
|
299
|
+
本项目采用“当前目录即当前工作区”的模型:
|
|
300
|
+
|
|
301
|
+
- 从哪个目录启动 `wechat-bridge-codex`,哪个目录就是当前工作区
|
|
302
|
+
- `wechat-codex` 必须连接同一工作区
|
|
303
|
+
- 不同工作区的状态文件相互隔离
|
|
304
|
+
|
|
305
|
+
当前不是“一个全局守护进程同时管理多个仓库”的架构,而是:
|
|
306
|
+
|
|
307
|
+
- 单 owner
|
|
308
|
+
- 单 bridge
|
|
309
|
+
- 单活动工作区
|
|
310
|
+
|
|
311
|
+
对 `wechat-codex-start` / `wechat-claude-start` / `wechat-opencode-start` 来说,这意味着:
|
|
312
|
+
|
|
313
|
+
- 它们是**单活工作区切换器**
|
|
314
|
+
- 当前目录重复执行是幂等的
|
|
315
|
+
- 其他目录重复执行会触发工作区切换,而不是并行多开
|
|
316
|
+
|
|
317
|
+
## 数据目录与状态文件
|
|
318
|
+
|
|
319
|
+
默认数据目录:
|
|
320
|
+
|
|
321
|
+
```text
|
|
322
|
+
~/.claude/channels/wechat
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
主要文件如下:
|
|
326
|
+
|
|
327
|
+
| 路径 | 作用 |
|
|
328
|
+
| --- | --- |
|
|
329
|
+
| `account.json` | 微信凭据 |
|
|
330
|
+
| `sync_buf.txt` | iLink 增量同步游标 |
|
|
331
|
+
| `context_tokens.json` | 微信上下文 token 缓存 |
|
|
332
|
+
| `bridge.log` | bridge 运行日志 |
|
|
333
|
+
| `bridge.lock.json` | bridge 运行锁 |
|
|
334
|
+
| `workspaces/<workspace-key>/bridge-state.json` | 当前工作区状态 |
|
|
335
|
+
| `workspaces/<workspace-key>/codex-panel-endpoint.json` | 当前工作区 panel endpoint |
|
|
336
|
+
|
|
337
|
+
### 环境变量
|
|
338
|
+
|
|
339
|
+
| 变量名 | 说明 |
|
|
340
|
+
| --- | --- |
|
|
341
|
+
| `WECHAT_ILINK_BASE_URL` | 覆盖默认 iLink API 地址 |
|
|
342
|
+
| `CLAUDE_WECHAT_CHANNEL_DATA_DIR` | 覆盖默认数据目录 |
|
|
343
|
+
|
|
344
|
+
## 版本更新
|
|
345
|
+
|
|
346
|
+
### 检查更新
|
|
347
|
+
|
|
348
|
+
运行以下命令检查是否有新版本:
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
wechat-check-update
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
该命令会显示:
|
|
355
|
+
- 当前安装的版本
|
|
356
|
+
- 远程仓库的最新版本
|
|
357
|
+
- 如果有更新,会提供详细的更新指引
|
|
358
|
+
|
|
359
|
+
### 启动时自动检查
|
|
360
|
+
|
|
361
|
+
当启动 `wechat-bridge` 相关命令时(如 `wechat-bridge-codex`、`wechat-bridge-claude`),程序会自动检查更新(每24小时一次)。
|
|
362
|
+
|
|
363
|
+
- 自动检查在后台异步执行,不影响启动速度
|
|
364
|
+
- 检查结果会被缓存,避免频繁查询
|
|
365
|
+
- 如果发现新版本,会在终端显示更新提示
|
|
366
|
+
|
|
367
|
+
### 版本检查机制
|
|
368
|
+
|
|
369
|
+
- **查询方式**:使用 `git ls-remote --tags origin` 查询远程仓库版本标签
|
|
370
|
+
- **缓存策略**:检查结果缓存在 `~/.claude/channels/wechat/update-check.json`,有效期24小时
|
|
371
|
+
- **无 API 限制**:不使用 GitHub API,避免限流问题,可以频繁使用
|
|
372
|
+
|
|
373
|
+
### 获取最新版本
|
|
374
|
+
|
|
375
|
+
当提示有新版本时,使用以下命令更新:
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
# 进入项目目录
|
|
379
|
+
cd CLI-WeChat-Bridge
|
|
380
|
+
|
|
381
|
+
# 拉取最新代码
|
|
382
|
+
git pull
|
|
383
|
+
|
|
384
|
+
# 安装依赖
|
|
385
|
+
bun install
|
|
386
|
+
|
|
387
|
+
# 重新安装全局命令
|
|
388
|
+
npm install -g .
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### 未来计划(还未发布)
|
|
392
|
+
|
|
393
|
+
当项目达到 **1.0.0** 稳定版本后,将发布到 npm,届时可以使用更简便的更新方式:
|
|
394
|
+
|
|
395
|
+
```bash
|
|
396
|
+
npm install -g @unlinearity/cli-wechat-bridge@latest
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
## 常见问题
|
|
400
|
+
|
|
401
|
+
### 1. `wechat-codex` 提示找不到 bridge
|
|
402
|
+
|
|
403
|
+
通常原因如下:
|
|
404
|
+
|
|
405
|
+
- 还没有先启动 `wechat-bridge-codex`
|
|
406
|
+
- bridge 与 panel 不在同一个目录
|
|
407
|
+
- 当前工作区 endpoint 文件不存在
|
|
408
|
+
|
|
409
|
+
建议:
|
|
410
|
+
|
|
411
|
+
1. 先在目标目录启动 `wechat-bridge-codex`
|
|
412
|
+
2. 再在同一目录启动 `wechat-codex`
|
|
413
|
+
|
|
414
|
+
如果你不想手动分两个终端,也可以直接执行:
|
|
415
|
+
|
|
416
|
+
```bash
|
|
417
|
+
wechat-codex-start
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### 2. 全局命令不存在
|
|
421
|
+
|
|
422
|
+
请确认已经执行以下之一:
|
|
423
|
+
|
|
424
|
+
```bash
|
|
425
|
+
npm install -g .
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
或:
|
|
429
|
+
|
|
430
|
+
```bash
|
|
431
|
+
npm link
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
如果命令仍不存在,请检查 npm 全局 bin 目录是否已加入 `PATH`。
|
|
435
|
+
|
|
436
|
+
### 3. Windows 下出现 `codex.ps1` 或 PowerShell profile 警告
|
|
437
|
+
|
|
438
|
+
项目已经尽量规避 `codex.ps1`:
|
|
439
|
+
|
|
440
|
+
- 优先查找 vendor `codex.exe`
|
|
441
|
+
- 必要时通过 `cmd.exe` 包装 `codex.cmd`
|
|
442
|
+
|
|
443
|
+
如果本机 PowerShell profile 本身受执行策略限制,终端仍可能打印相关警告。这通常不是 bridge 本身故障。
|
|
444
|
+
|
|
445
|
+
### 4. 微信上提示没有 context token
|
|
446
|
+
|
|
447
|
+
通常表示当前联系人还没有建立可用的 iLink 上下文。一般先由 owner 账号发送一条普通消息即可建立上下文。
|
|
448
|
+
|
|
449
|
+
### 5. `codex is still working...`
|
|
450
|
+
|
|
451
|
+
该提示只应在当前确实存在活动任务时出现。
|
|
452
|
+
|
|
453
|
+
如果偶发出现:
|
|
454
|
+
|
|
455
|
+
1. 先确认本地 `wechat-codex` 是否真的仍在执行任务
|
|
456
|
+
2. 必要时使用 `/stop`
|
|
457
|
+
3. 检查:
|
|
458
|
+
|
|
459
|
+
```text
|
|
460
|
+
~/.claude/channels/wechat/bridge.log
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### 6. 本地 `/resume` 后微信不同步
|
|
464
|
+
|
|
465
|
+
请优先确认: `wechat-bridge-codex` 与 `wechat-codex` 是否都已重启到同一版本。
|
|
466
|
+
|
|
467
|
+
部分设备可能存在第一次本地输入不同步到微信的情况,可以先微信发送指令来建立连接。
|
|
468
|
+
|
|
469
|
+
## 已知限制
|
|
470
|
+
|
|
471
|
+
- 微信 `/resume` 暂时被禁用(可能导致对话双向不稳定)
|
|
472
|
+
- Codex 不支持底层任务的远程审批!建议给好权限,正常使用,几乎不会主动请求较为低级的远程审批;Claude Code 支持远程审批,但是测试的不够,如有问题可以提 issue。
|
|
473
|
+
- 当前模型是单 owner、单 bridge、单活动工作区
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
## 开发说明
|
|
477
|
+
|
|
478
|
+
### 主要入口
|
|
479
|
+
|
|
480
|
+
| 文件 | 作用 |
|
|
481
|
+
| --- | --- |
|
|
482
|
+
| `src/bridge/wechat-bridge.ts` | bridge 主事件循环 |
|
|
483
|
+
| `src/bridge/bridge-adapters.ts` | `codex` / `claude` / `shell` 适配器实现 |
|
|
484
|
+
| `src/companion/local-companion.ts` | `wechat-codex` / `wechat-claude` 本地 companion 入口 |
|
|
485
|
+
| `src/companion/codex-panel.ts` | Codex panel 入口(备用) |
|
|
486
|
+
| `src/companion/codex-panel-link.ts` | bridge 与 Codex panel 的本地 IPC |
|
|
487
|
+
| `src/wechat/wechat-transport.ts` | iLink 消息收发 |
|
|
488
|
+
| `src/bridge/bridge-state.ts` | bridge 状态、锁与日志 |
|
|
489
|
+
| `src/wechat/setup.ts` | 登录与凭据初始化 |
|
|
490
|
+
|
|
491
|
+
### 测试
|
|
492
|
+
|
|
493
|
+
```bash
|
|
494
|
+
bun test
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
当前测试主要覆盖:
|
|
498
|
+
|
|
499
|
+
- Windows 启动解析
|
|
500
|
+
- Codex 线程跟随
|
|
501
|
+
- session log fallback
|
|
502
|
+
- panel / busy / completion recovery
|
|
503
|
+
- 工作区路径与状态隔离
|
|
504
|
+
|
|
505
|
+
## 致谢
|
|
506
|
+
|
|
507
|
+
### 相关链接
|
|
508
|
+
- [Linux DO](https://linux.do/):学AI,上L站!
|
|
509
|
+
|
|
510
|
+
- [openclaw-weixin](https://github.com/hao-ji-xing/openclaw-weixin):支持Claude Code Channel,感谢如此迅速的开源。
|
|
511
|
+
|
|
512
|
+
- [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk):TypeScript 版 MCP SDK
|
|
513
|
+
|
|
514
|
+
- [node-pty](https://github.com/microsoft/node-pty):本地 PTY / ConPTY 进程桥接
|
|
515
|
+
|
|
516
|
+
- [@anthropic-ai/sdk](https://github.com/anthropics/anthropic-sdk-typescript):Anthropic TypeScript SDK
|
|
517
|
+
|
|
518
|
+
- [qrcode-terminal](https://github.com/gtanner/qrcode-terminal):终端二维码输出
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
### 感谢支持
|
|
522
|
+
|
|
523
|
+
> 感谢 issue 反馈者 和 pr 贡献者。
|
|
524
|
+
|
|
525
|
+
创作不易,如感觉对您有帮助、觉得有意思,可以请喝杯奶茶。❤️
|
|
526
|
+
|
|
527
|
+
<p align='center'><img src='docs\images\wechat-tip.png' width=60%></p>
|
|
528
|
+
|
|
529
|
+
## License
|
|
530
|
+
|
|
531
|
+
[MIT](LICENSE.txt)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
const BIN_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const PROJECT_DIR = path.resolve(BIN_DIR, "..");
|
|
9
|
+
|
|
10
|
+
export function runTsEntry(relativeEntryPath, extraArgs = []) {
|
|
11
|
+
const entryPath = path.join(PROJECT_DIR, relativeEntryPath);
|
|
12
|
+
const child = spawn(
|
|
13
|
+
process.execPath,
|
|
14
|
+
[
|
|
15
|
+
"--no-warnings",
|
|
16
|
+
"--experimental-strip-types",
|
|
17
|
+
entryPath,
|
|
18
|
+
...extraArgs,
|
|
19
|
+
...process.argv.slice(2),
|
|
20
|
+
],
|
|
21
|
+
{
|
|
22
|
+
stdio: "inherit",
|
|
23
|
+
cwd: process.cwd(),
|
|
24
|
+
env: process.env,
|
|
25
|
+
},
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
child.once("error", (error) => {
|
|
29
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
30
|
+
process.stderr.write(`${message}\n`);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
child.once("exit", (code, signal) => {
|
|
35
|
+
if (signal) {
|
|
36
|
+
process.kill(process.pid, signal);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
process.exit(code ?? 0);
|
|
40
|
+
});
|
|
41
|
+
}
|