claude-codex-wechat 0.1.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/README.md ADDED
@@ -0,0 +1,558 @@
1
+ # claude-codex-wechat
2
+
3
+ `claude-codex-wechat` 是一个本地桥接服务,用来把:
4
+
5
+ - 微信 bot 通道
6
+ - 本地原生 `Claude Code`
7
+ - 本地原生 `Codex CLI`
8
+
9
+ 接起来,让你可以直接在微信里和本机上的 `Claude Code` / `Codex` 对话,并保留本地原生会话恢复能力。
10
+
11
+ 这个项目的定位是:
12
+
13
+ - **本地运行**
14
+ - **微信 -> 本地原生 CLI**
15
+ - **Native Provider Bridge**
16
+ - **不是 ACP bridge**
17
+
18
+ ---
19
+
20
+ ## 项目做什么
21
+
22
+ 这个仓库当前已经实现的主能力有:
23
+
24
+ - 微信 direct 模式接入,走官方 `getupdates` / `sendmessage`
25
+ - 微信扫码登录与 bot token 获取
26
+ - 微信消息路由到本地 `Claude Code` / `Codex CLI`
27
+ - 会话持久化到 SQLite
28
+ - 原生 Claude / Codex 会话扫描
29
+ - 原生会话手动接入
30
+ - 原生会话自动接入
31
+ - 桥接会话与原生会话绑定持久化
32
+ - 管理页支持:
33
+ - pairing 审批
34
+ - 授权用户管理
35
+ - provider 切换
36
+ - 会话停止 / 归档
37
+ - 权限审批
38
+ - 原生恢复修复
39
+ - Claude 原生恢复能力:
40
+ - `claude --resume <sessionId>`
41
+ - `claude -r '<完整标题>'`
42
+ - Codex 原生恢复能力:
43
+ - `codex resume <sessionId>`
44
+ - `codex resume '<thread_name>'`
45
+
46
+ ---
47
+
48
+ ## 当前实现目标
49
+
50
+ 这个仓库的核心目标不是“做一个微信聊天 UI”,而是:
51
+
52
+ 1. 把微信消息稳定接进本地 bridge
53
+ 2. 把 bridge 会话稳定映射到本地原生 Claude / Codex 会话
54
+ 3. 让微信侧会话尽可能和本地原生会话恢复链路对齐
55
+
56
+ 其中 Claude 这条链路尤其强调:
57
+
58
+ - bridge session 有自己的 `resumeTitle`
59
+ - 原生会话文件里有对应标题
60
+ - `~/.claude/history.jsonl` 里也有对应标题
61
+
62
+ 只有这几层都对齐,`claude -r '<完整标题>'` 才真正可用。
63
+
64
+ ---
65
+
66
+ ## 目录说明
67
+
68
+ 主要目录:
69
+
70
+ - `src/`
71
+ - bridge 主实现
72
+ - 微信通道
73
+ - provider 接入
74
+ - daemon / admin routes / web
75
+ - `tests/`
76
+ - 单元测试
77
+ - bridge 运行态测试
78
+ - 微信 direct 流程测试
79
+ - 前端交互测试
80
+ - `scripts/`
81
+ - 正式恢复入口
82
+ - 联调启动脚本
83
+ - 诊断脚本
84
+ - `docs/`
85
+ - 详细运行说明
86
+ - 对齐过程文档
87
+ - 参考实现文档
88
+
89
+ 脚本分层索引见:
90
+
91
+ - [scripts/README.md](./scripts/README.md)
92
+
93
+ ---
94
+
95
+ ## 安装
96
+
97
+ ### 方式 A:作为 npm 包全局安装(推荐普通用户)
98
+
99
+ ```bash
100
+ npm install -g claude-codex-wechat
101
+ # 或
102
+ pnpm add -g claude-codex-wechat
103
+ ```
104
+
105
+ > 该包依赖原生模块 `better-sqlite3`,安装时会优先下载预编译二进制;少数环境(非主流架构 / 离线)可能需要本地编译工具链(Node ≥ 20、Python、C++ 编译器)。
106
+
107
+ 安装后会得到一个全局命令 `claude-codex-wechat`:
108
+
109
+ ```bash
110
+ claude-codex-wechat init # 在 ~/.claude-codex-wechat/ 写入默认配置
111
+ claude-codex-wechat doctor # 检查配置、前端产物、claude/codex 可执行文件
112
+ claude-codex-wechat start # 前台启动 daemon(默认命令)
113
+ claude-codex-wechat print-config # 打印当前配置
114
+ claude-codex-wechat help # 查看全部命令
115
+ ```
116
+
117
+ 启动后访问 `http://127.0.0.1:8787`(端口由 `BRIDGE_PORT` 控制)。
118
+
119
+ 前置条件:本机已安装并登录好 `Claude Code` / `Codex CLI`,且准备好微信 bot 的 `token` / `accountId`。
120
+
121
+ ### 方式 B:从源码开发
122
+
123
+ ```bash
124
+ cd /path/to/claude-codex-wechat
125
+ pnpm install
126
+ ```
127
+
128
+ ---
129
+
130
+ ## 本地启动(开发模式)
131
+
132
+ 一条命令同时启动后端与前端管理页(前端以 Vite middleware 模式嵌入同一进程,含热更新):
133
+
134
+ ```bash
135
+ pnpm dev
136
+ ```
137
+
138
+ 启动后访问 `http://127.0.0.1:8787`(端口由 `BRIDGE_PORT` 控制)。
139
+
140
+ 基础校验与构建:
141
+
142
+ ```bash
143
+ pnpm typecheck
144
+ pnpm test
145
+ pnpm build # = vite build(前端 -> dist/web)+ esbuild(server -> dist/server/cli.js)
146
+ ```
147
+
148
+ 构建产物:
149
+
150
+ - `dist/web/` —— 前端静态资源(生产态由 `@fastify/static` 服务)
151
+ - `dist/server/cli.js` —— CLI / daemon 入口(对应 `bin` 字段)
152
+
153
+ ---
154
+
155
+ ## 配置
156
+
157
+ 默认配置文件路径:
158
+
159
+ ```text
160
+ ~/.claude-codex-wechat/config.json
161
+ ```
162
+
163
+ 可以从示例复制:
164
+
165
+ ```bash
166
+ mkdir -p ~/.claude-codex-wechat
167
+ cp config.example.json ~/.claude-codex-wechat/config.json
168
+ ```
169
+
170
+ 最小配置示例:
171
+
172
+ ```json
173
+ {
174
+ "databasePath": "/Users/you/.claude-codex-wechat/bridge.sqlite",
175
+ "wechat": {
176
+ "enabled": true,
177
+ "baseUrl": "https://ilinkai.weixin.qq.com",
178
+ "token": "replace-with-weixin-bot-token",
179
+ "accountId": "replace-with-weixin-account-id"
180
+ },
181
+ "providers": {
182
+ "claude": {
183
+ "command": "/opt/homebrew/bin/claude"
184
+ },
185
+ "codex": {
186
+ "command": "/opt/homebrew/bin/codex"
187
+ }
188
+ }
189
+ }
190
+ ```
191
+
192
+ 常用环境变量:
193
+
194
+ - `BRIDGE_PORT`
195
+ - `BRIDGE_CONFIG`
196
+ - `BRIDGE_WECHAT_ENABLED`
197
+ - `BRIDGE_WECHAT_BASE_URL`
198
+ - `BRIDGE_WECHAT_TOKEN`
199
+ - `BRIDGE_WECHAT_ACCOUNT_ID`
200
+ - `BRIDGE_CLAUDE_COMMAND`
201
+ - `BRIDGE_CODEX_COMMAND`
202
+
203
+ ---
204
+
205
+ ## 常驻运行(守护进程)
206
+
207
+ `claude-codex-wechat start` 默认前台运行。npm 本身不负责守护,长期常驻建议交给成熟的进程管理器。下面三种任选其一。
208
+
209
+ ### 方式一:pm2(跨平台,最简单)
210
+
211
+ ```bash
212
+ npm install -g pm2
213
+ pm2 start claude-codex-wechat --name ccwx -- start
214
+ pm2 logs ccwx # 看日志
215
+ pm2 restart ccwx # 重启
216
+ pm2 startup && pm2 save # 开机自启
217
+ ```
218
+
219
+ 如需自定义端口 / 配置:
220
+
221
+ ```bash
222
+ BRIDGE_PORT=8787 pm2 start claude-codex-wechat --name ccwx -- start
223
+ ```
224
+
225
+ ### 方式二:systemd(Linux)
226
+
227
+ 创建 `/etc/systemd/system/claude-codex-wechat.service`(把 `User` 和 `ExecStart` 路径换成你的实际值,`which claude-codex-wechat` 可查路径):
228
+
229
+ ```ini
230
+ [Unit]
231
+ Description=claude-codex-wechat bridge daemon
232
+ After=network.target
233
+
234
+ [Service]
235
+ Type=simple
236
+ User=youruser
237
+ Environment=BRIDGE_PORT=8787
238
+ # 如需指定配置文件:Environment=BRIDGE_CONFIG=/home/youruser/.claude-codex-wechat/config.json
239
+ ExecStart=/usr/bin/claude-codex-wechat start
240
+ Restart=on-failure
241
+ RestartSec=5
242
+
243
+ [Install]
244
+ WantedBy=multi-user.target
245
+ ```
246
+
247
+ 启用:
248
+
249
+ ```bash
250
+ sudo systemctl daemon-reload
251
+ sudo systemctl enable --now claude-codex-wechat
252
+ sudo journalctl -u claude-codex-wechat -f # 看日志
253
+ ```
254
+
255
+ ### 方式三:launchd(macOS)
256
+
257
+ 创建 `~/Library/LaunchAgents/com.claude-codex-wechat.plist`(把 `ProgramArguments` 第一项换成 `which claude-codex-wechat` 的实际路径):
258
+
259
+ ```xml
260
+ <?xml version="1.0" encoding="UTF-8"?>
261
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
262
+ <plist version="1.0">
263
+ <dict>
264
+ <key>Label</key>
265
+ <string>com.claude-codex-wechat</string>
266
+ <key>ProgramArguments</key>
267
+ <array>
268
+ <string>/opt/homebrew/bin/claude-codex-wechat</string>
269
+ <string>start</string>
270
+ </array>
271
+ <key>EnvironmentVariables</key>
272
+ <dict>
273
+ <key>BRIDGE_PORT</key>
274
+ <string>8787</string>
275
+ </dict>
276
+ <key>RunAtLoad</key>
277
+ <true/>
278
+ <key>KeepAlive</key>
279
+ <true/>
280
+ <key>StandardOutPath</key>
281
+ <string>/tmp/claude-codex-wechat.out.log</string>
282
+ <key>StandardErrorPath</key>
283
+ <string>/tmp/claude-codex-wechat.err.log</string>
284
+ </dict>
285
+ </plist>
286
+ ```
287
+
288
+ 加载:
289
+
290
+ ```bash
291
+ launchctl load ~/Library/LaunchAgents/com.claude-codex-wechat.plist
292
+ launchctl list | grep claude-codex-wechat # 确认在跑
293
+ # 卸载:launchctl unload ~/Library/LaunchAgents/com.claude-codex-wechat.plist
294
+ ```
295
+
296
+ ---
297
+
298
+ ## 正常使用路径
299
+
300
+ ### 1. 首次使用或微信 token 失效后恢复
301
+
302
+ 最推荐的正式入口:
303
+
304
+ ```bash
305
+ bash ./scripts/recover-weixin-runtime.sh
306
+ ```
307
+
308
+ 如果你要直接做 Codex 验收模式:
309
+
310
+ ```bash
311
+ BRIDGE_DEFAULT_PROVIDER=codex bash ./scripts/recover-weixin-runtime.sh
312
+ ```
313
+
314
+ 这条命令会自动完成:
315
+
316
+ 1. 拉取新的微信登录二维码
317
+ 2. 生成并自动打开二维码 SVG
318
+ 3. 等待扫码确认
319
+ 4. 写出新的微信凭据文件
320
+ 5. 启动最新 bridge runtime
321
+
322
+ 如果设置了:
323
+
324
+ ```bash
325
+ BRIDGE_DEFAULT_PROVIDER=codex
326
+ ```
327
+
328
+ 那么 runtime 启动后会自动把默认 provider 切到 `codex`。
329
+
330
+ 二维码文件默认路径:
331
+
332
+ ```text
333
+ /tmp/bridge-weixin-login-qr.svg
334
+ ```
335
+
336
+ 扫码状态文件默认路径:
337
+
338
+ ```text
339
+ /tmp/bridge-weixin-login-state.json
340
+ ```
341
+
342
+ 凭据文件默认路径:
343
+
344
+ ```text
345
+ /tmp/bridge-weixin-credentials.json
346
+ /tmp/bridge-weixin.env
347
+ ```
348
+
349
+ 注意:
350
+
351
+ - 这两个 `/tmp` 文件仍然会生成,方便联调和显式 `source`
352
+ - 扫码成功后,helper 现在也会自动把新凭据回写到 `~/.claude-codex-wechat/config.json`
353
+ - 之后直接执行 `pnpm dev`,默认就会继续读取这份正式配置
354
+
355
+ 最少要同步这几个字段:
356
+
357
+ - `wechat.baseUrl`
358
+ - `wechat.token`
359
+ - `wechat.accountId`
360
+
361
+ 否则你会看到一种典型现象:
362
+
363
+ - 扫码后当前 runtime 能用
364
+ - 重启 `pnpm dev` 后又读不到刚才的新凭据
365
+ - 看起来像“每次重启都要重新扫码”
366
+
367
+ ### 2. 启动成功后检查 bridge 是否真的连通
368
+
369
+ ```bash
370
+ BRIDGE_PORT=8788 bash ./scripts/check-runtime-readiness.sh
371
+ ```
372
+
373
+ 重点看:
374
+
375
+ - `weixin_connected`
376
+ - `weixin_status`
377
+ - `weixin_last_error`
378
+
379
+ 如果是正常连通,通常应该看到:
380
+
381
+ - `weixin_connected=true`
382
+ - `weixin_status=connected`
383
+
384
+ ### 3. 发微信消息开始对话
385
+
386
+ 给当前 bot 账号发一条文本消息。
387
+
388
+ bridge 收到消息后会:
389
+
390
+ - 自动授权用户(如果设置中开启)
391
+ - 创建或接入 bridge session
392
+ - 默认用当前设置的 provider 对话
393
+
394
+ ---
395
+
396
+ ## 管理页有哪些功能
397
+
398
+ 当前管理页主要分成 4 块:
399
+
400
+ ### 1. Dashboard
401
+
402
+ - daemon 状态
403
+ - provider 状态
404
+ - 活跃会话数
405
+ - 待处理权限数
406
+
407
+ ### 2. WeChatPanel
408
+
409
+ - 微信扫码登录
410
+ - pairing 待审批列表
411
+ - 批准 / 拒绝 pairing
412
+ - 已授权用户管理
413
+ - 撤销授权
414
+ - 扫描可恢复原生会话
415
+ - 手动接入原生会话
416
+ - 自动接入原生会话
417
+ - Claude recoverable session 修复
418
+
419
+ ### 3. SessionsPanel
420
+
421
+ - 查看 bridge 会话
422
+ - 查看推荐恢复命令
423
+ - 查看 provider resume 命令
424
+ - 停止会话
425
+ - 归档会话
426
+ - 查看原生可达路径
427
+ - 查看绑定来源
428
+ - 单个 / 批量修复 Claude 原生恢复元数据
429
+
430
+ ### 4. PermissionsPanel
431
+
432
+ - 批准 / 拒绝 / 中止高风险权限请求
433
+
434
+ ---
435
+
436
+ ## 原生恢复能力
437
+
438
+ ### Claude
439
+
440
+ 当前仓库支持两种恢复方式:
441
+
442
+ 按原生 session id:
443
+
444
+ ```bash
445
+ claude --resume <providerSessionId>
446
+ ```
447
+
448
+ 按 bridge 标题:
449
+
450
+ ```bash
451
+ claude -r '<完整标题>'
452
+ ```
453
+
454
+ 要让 `claude -r` 真正可用,通常至少要满足:
455
+
456
+ - `providerResumeTitleSynced = true`
457
+ - `providerResumeHistorySynced = true`
458
+
459
+ ### Codex
460
+
461
+ 按 session id:
462
+
463
+ ```bash
464
+ codex resume <providerSessionId>
465
+ ```
466
+
467
+ 按 bridge thread name:
468
+
469
+ ```bash
470
+ codex resume '<thread_name>'
471
+ ```
472
+
473
+ ---
474
+
475
+ ## 脚本怎么分
476
+
477
+ ### 正式使用入口
478
+
479
+ - `scripts/recover-weixin-runtime.sh`
480
+ 最推荐的恢复入口
481
+ - `scripts/weixin-login-helper.ts`
482
+ 单独扫码与落盘凭据
483
+ - `scripts/start-runtime-check.sh`
484
+ 启动最新 runtime 并打印关键状态
485
+
486
+ ### 诊断 / 验收工具
487
+
488
+ - `scripts/check-runtime-readiness.sh`
489
+ 看 bridge 是否真的连通
490
+ - `scripts/check-runtime-recovery.sh`
491
+ 看 bridge session 恢复字段
492
+ - `scripts/check-weixin-updates.ts`
493
+ 直接打微信官方 `getupdates`
494
+
495
+ 如果只想记一个命令:
496
+
497
+ ```bash
498
+ bash ./scripts/recover-weixin-runtime.sh
499
+ ```
500
+
501
+ 如果要直接推进 Codex 的真实闭环验收,建议用这一组:
502
+
503
+ ```bash
504
+ BRIDGE_DEFAULT_PROVIDER=codex bash ./scripts/recover-weixin-runtime.sh
505
+ BRIDGE_PORT=8788 WAIT_SECONDS=120 bash ./scripts/check-codex-wechat-flow.sh
506
+ ```
507
+
508
+ ---
509
+
510
+ ## 当前已知边界
511
+
512
+ 这个仓库当前已经把工程内能做的链路基本铺平了,但仍有一个非常现实的边界:
513
+
514
+ - 微信 bot 新授权出来的 token 可能会很快再次 `session timeout`
515
+
516
+ 也就是说,即使:
517
+
518
+ - 扫码成功
519
+ - 新 token 落盘成功
520
+ - 最新 runtime 能启动
521
+
522
+ 微信官方 `getupdates` 会话本身仍可能在很短时间后再次失效。
523
+
524
+ 如果出现:
525
+
526
+ - `weixin_connected=false`
527
+ - `weixin_status=session_timeout`
528
+ - `weixin_last_error=weixin_get_updates_failed:-14:session timeout`
529
+
530
+ 这更像是微信侧登录 / updates 会话稳定性问题,而不一定是这个 bridge 的业务逻辑问题。
531
+
532
+ ---
533
+
534
+ ## 怎么判断真正成功
535
+
536
+ 一个最小闭环应至少满足:
537
+
538
+ 1. `check-runtime-readiness.sh` 显示:
539
+ - `weixin_connected=true`
540
+ - `weixin_status=connected`
541
+ 2. 给 bot 发一条真实微信消息后:
542
+ - `/api/channel/sessions` 出现新会话
543
+ 3. Claude 会话里看到:
544
+ - `providerResumeTitleSynced=true`
545
+ - `providerResumeHistorySynced=true`
546
+ 4. `claude -r '<完整标题>'` 真能恢复
547
+
548
+ 如果要验 Codex,则再满足:
549
+
550
+ 5. `codex resume '<thread_name>'` 真能恢复
551
+
552
+ ---
553
+
554
+ ## 更多文档
555
+
556
+ - [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md) —— 架构总览:整体架构、数据流、目录结构
557
+ - [docs/README.md](./docs/README.md)
558
+ - [scripts/README.md](./scripts/README.md)
@@ -0,0 +1,18 @@
1
+ {
2
+ "databasePath": "/Users/you/.claude-codex-wechat/bridge.sqlite",
3
+ "wechat": {
4
+ "enabled": true,
5
+ "mode": "direct",
6
+ "baseUrl": "https://ilinkai.weixin.qq.com",
7
+ "token": "replace-with-weixin-bot-token",
8
+ "accountId": "replace-with-weixin-account-id"
9
+ },
10
+ "providers": {
11
+ "claude": {
12
+ "command": "/opt/homebrew/bin/claude"
13
+ },
14
+ "codex": {
15
+ "command": "/opt/homebrew/bin/codex"
16
+ }
17
+ }
18
+ }