cc-wechat 0.3.1 → 0.5.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/src/cli.ts CHANGED
@@ -1,121 +1,124 @@
1
- #!/usr/bin/env node
2
- /**
3
- * cc-wechat CLI 入口 — install/login/status/help 命令
4
- */
5
-
6
- import { execSync } from 'node:child_process';
7
- import path from 'node:path';
8
- import { fileURLToPath } from 'node:url';
9
- import { loginTerminal } from './auth.js';
10
- import { saveAccount, getActiveAccount } from './store.js';
11
-
12
- // ─── help ────────────────────────────────────────────
13
-
14
- /** 打印帮助信息 */
15
- function help(): void {
16
- console.log(`
17
- cc-wechat 微信 Claude Code Channel 插件
18
-
19
- 用法: npx cc-wechat <命令>
20
-
21
- 命令:
22
- install 注册 MCP server + 扫码登录
23
- patch 修补 Claude Code 以启用 Channels 功能
24
- unpatch 恢复原始 Claude Code
25
- login 重新扫码登录
26
- status 查看连接状态
27
- help 显示帮助
28
- `);
29
- }
30
-
31
- // ─── install ─────────────────────────────────────────
32
-
33
- /** 注册 MCP server + 扫码登录 */
34
- async function install(): Promise<void> {
35
- console.log('\n🔧 cc-wechat 安装向导\n');
36
-
37
- // [1/3] 注册 MCP server
38
- console.log('[1/3] 注册 MCP server...');
39
- const serverPath = path.join(path.dirname(fileURLToPath(import.meta.url)), 'server.js');
40
-
41
- try {
42
- execSync('claude mcp add -s user wechat-channel node ' + serverPath, { stdio: 'pipe' });
43
- console.log(' ✅ MCP server 已注册');
44
- } catch {
45
- try {
46
- execSync('claude mcp remove wechat-channel', { stdio: 'pipe' });
47
- execSync('claude mcp add -s user wechat-channel node ' + serverPath, { stdio: 'pipe' });
48
- console.log(' ✅ MCP server 已重新注册');
49
- } catch (e) {
50
- console.error(' MCP server 注册失败:', (e as Error).message);
51
- }
52
- }
53
-
54
- // [2/3] 微信扫码登录
55
- console.log('\n[2/3] 微信扫码登录...');
56
- const existing = getActiveAccount();
57
- if (existing) {
58
- console.log(' ⏭️ 已有登录账号,跳过扫码。如需重新登录请运行: npx cc-wechat login');
59
- } else {
60
- const { token, accountId, baseUrl } = await loginTerminal();
61
- saveAccount({
62
- token,
63
- baseUrl: baseUrl ?? '',
64
- botId: accountId.replace(/@/g, '-').replace(/\./g, '-'),
65
- savedAt: new Date().toISOString(),
66
- });
67
- console.log(' 登录成功');
68
- }
69
-
70
- // [3/3] 完成
71
- console.log('\n[3/3] 安装完成!');
72
- console.log('\n启动 Claude Code 时使用:');
73
- console.log(' claude --dangerously-load-development-channels server:wechat-channel\n');
74
- }
75
-
76
- // ─── login ───────────────────────────────────────────
77
-
78
- /** 重新扫码登录 */
79
- async function login(): Promise<void> {
80
- console.log('\n🔑 微信扫码登录\n');
81
- const { token, accountId, baseUrl } = await loginTerminal();
82
- saveAccount({
83
- token,
84
- baseUrl: baseUrl ?? '',
85
- botId: accountId.replace(/@/g, '-').replace(/\./g, '-'),
86
- savedAt: new Date().toISOString(),
87
- });
88
- console.log('\n✅ 登录成功!账号已保存。\n');
89
- }
90
-
91
- // ─── status ──────────────────────────────────────────
92
-
93
- /** 查看连接状态 */
94
- function status(): void {
95
- const account = getActiveAccount();
96
- if (account) {
97
- console.log('\n📋 当前账号状态:\n');
98
- console.log(` botId: ${account.botId.substring(0, 12)}...`);
99
- console.log(` baseUrl: ${account.baseUrl}`);
100
- console.log(` savedAt: ${account.savedAt}\n`);
101
- } else {
102
- console.log('\n❌ 尚未登录。请运行: npx cc-wechat install\n');
103
- }
104
- }
105
-
106
- // ─── main ────────────────────────────────────────────
107
-
108
- const command = process.argv[2];
109
- switch (command) {
110
- case 'install': case 'setup': install(); break;
111
- case 'login': login(); break;
112
- case 'patch': case 'unpatch': {
113
- // 动态导入 patch 模块,传递命令
114
- process.argv[2] = command;
115
- await import('./patch.js');
116
- break;
117
- }
118
- case 'status': status(); break;
119
- case 'help': case '--help': case '-h': case undefined: help(); break;
120
- default: console.error(`未知命令: ${command}`); help(); process.exit(1);
121
- }
1
+ #!/usr/bin/env node
2
+ /**
3
+ * cc-wechat CLI 入口 — install/login/status/help 命令
4
+ */
5
+
6
+ // 代理支持(必须最先导入)
7
+ import './proxy.js';
8
+
9
+ import { execSync } from 'node:child_process';
10
+ import path from 'node:path';
11
+ import { fileURLToPath } from 'node:url';
12
+ import { loginTerminal } from './auth.js';
13
+ import { saveAccount, getActiveAccount } from './store.js';
14
+
15
+ // ─── help ────────────────────────────────────────────
16
+
17
+ /** 打印帮助信息 */
18
+ function help(): void {
19
+ console.log(`
20
+ cc-wechat — 微信 Claude Code Channel 插件
21
+
22
+ 用法: npx cc-wechat <命令>
23
+
24
+ 命令:
25
+ install 注册 MCP server + 扫码登录
26
+ patch 修补 Claude Code 以启用 Channels 功能
27
+ unpatch 恢复原始 Claude Code
28
+ login 重新扫码登录
29
+ status 查看连接状态
30
+ help 显示帮助
31
+ `);
32
+ }
33
+
34
+ // ─── install ─────────────────────────────────────────
35
+
36
+ /** 注册 MCP server + 扫码登录 */
37
+ async function install(): Promise<void> {
38
+ console.log('\n🔧 cc-wechat 安装向导\n');
39
+
40
+ // [1/3] 注册 MCP server
41
+ console.log('[1/3] 注册 MCP server...');
42
+ const serverPath = path.join(path.dirname(fileURLToPath(import.meta.url)), 'server.js');
43
+
44
+ try {
45
+ execSync('claude mcp add -s user wechat-channel node ' + serverPath, { stdio: 'pipe' });
46
+ console.log(' MCP server 已注册');
47
+ } catch {
48
+ try {
49
+ execSync('claude mcp remove wechat-channel', { stdio: 'pipe' });
50
+ execSync('claude mcp add -s user wechat-channel node ' + serverPath, { stdio: 'pipe' });
51
+ console.log(' ✅ MCP server 已重新注册');
52
+ } catch (e) {
53
+ console.error(' ❌ MCP server 注册失败:', (e as Error).message);
54
+ }
55
+ }
56
+
57
+ // [2/3] 微信扫码登录
58
+ console.log('\n[2/3] 微信扫码登录...');
59
+ const existing = getActiveAccount();
60
+ if (existing) {
61
+ console.log(' ⏭️ 已有登录账号,跳过扫码。如需重新登录请运行: npx cc-wechat login');
62
+ } else {
63
+ const { token, accountId, baseUrl } = await loginTerminal();
64
+ saveAccount({
65
+ token,
66
+ baseUrl: baseUrl ?? '',
67
+ botId: accountId.replace(/@/g, '-').replace(/\./g, '-'),
68
+ savedAt: new Date().toISOString(),
69
+ });
70
+ console.log(' 登录成功');
71
+ }
72
+
73
+ // [3/3] 完成
74
+ console.log('\n[3/3] 安装完成!');
75
+ console.log('\n启动 Claude Code 时使用:');
76
+ console.log(' claude --dangerously-load-development-channels server:wechat-channel\n');
77
+ }
78
+
79
+ // ─── login ───────────────────────────────────────────
80
+
81
+ /** 重新扫码登录 */
82
+ async function login(): Promise<void> {
83
+ console.log('\n🔑 微信扫码登录\n');
84
+ const { token, accountId, baseUrl } = await loginTerminal();
85
+ saveAccount({
86
+ token,
87
+ baseUrl: baseUrl ?? '',
88
+ botId: accountId.replace(/@/g, '-').replace(/\./g, '-'),
89
+ savedAt: new Date().toISOString(),
90
+ });
91
+ console.log('\n✅ 登录成功!账号已保存。\n');
92
+ }
93
+
94
+ // ─── status ──────────────────────────────────────────
95
+
96
+ /** 查看连接状态 */
97
+ function status(): void {
98
+ const account = getActiveAccount();
99
+ if (account) {
100
+ console.log('\n📋 当前账号状态:\n');
101
+ console.log(` botId: ${account.botId.substring(0, 12)}...`);
102
+ console.log(` baseUrl: ${account.baseUrl}`);
103
+ console.log(` savedAt: ${account.savedAt}\n`);
104
+ } else {
105
+ console.log('\n❌ 尚未登录。请运行: npx cc-wechat install\n');
106
+ }
107
+ }
108
+
109
+ // ─── main ────────────────────────────────────────────
110
+
111
+ const command = process.argv[2];
112
+ switch (command) {
113
+ case 'install': case 'setup': install(); break;
114
+ case 'login': login(); break;
115
+ case 'patch': case 'unpatch': {
116
+ // 动态导入 patch 模块,传递命令
117
+ process.argv[2] = command;
118
+ await import('./patch.js');
119
+ break;
120
+ }
121
+ case 'status': status(); break;
122
+ case 'help': case '--help': case '-h': case undefined: help(); break;
123
+ default: console.error(`未知命令: ${command}`); help(); process.exit(1);
124
+ }
package/src/ilink-api.ts CHANGED
@@ -178,27 +178,34 @@ export async function getUpdates(
178
178
  }
179
179
  }
180
180
 
181
- /** 发送文本消息,返回 client_id */
181
+ /** 发送文本消息,返回 client_id。支持引用回复(ref_msg) */
182
182
  export async function sendMessage(
183
183
  token: string,
184
184
  to: string,
185
185
  text: string,
186
186
  contextToken: string,
187
187
  baseUrl?: string,
188
+ refMsgId?: string,
188
189
  ): Promise<string> {
189
190
  const clientId = `cc-wechat-${randomBytes(4).toString('hex')}`;
190
- const body = JSON.stringify({
191
- msg: {
192
- from_user_id: '',
193
- to_user_id: to,
194
- client_id: clientId,
195
- message_type: 2,
196
- message_state: 2,
197
- item_list: [{ type: 1, text_item: { text } }],
198
- context_token: contextToken,
199
- },
200
- base_info: buildBaseInfo(),
201
- });
191
+ // 构造消息内容项,支持引用回复
192
+ const textItem: Record<string, unknown> = { type: 1, text_item: { text } };
193
+ if (refMsgId) {
194
+ textItem.ref_msg = { title: text.slice(0, 40) };
195
+ }
196
+ const msg: Record<string, unknown> = {
197
+ from_user_id: '',
198
+ to_user_id: to,
199
+ client_id: clientId,
200
+ message_type: 2,
201
+ message_state: 2,
202
+ item_list: [textItem],
203
+ context_token: contextToken,
204
+ };
205
+ if (refMsgId) {
206
+ msg.ref_message_id = refMsgId;
207
+ }
208
+ const body = JSON.stringify({ msg, base_info: buildBaseInfo() });
202
209
  await apiFetch({
203
210
  baseUrl,
204
211
  endpoint: 'ilink/bot/sendmessage',
package/src/proxy.ts ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 代理支持 — 检测 HTTPS_PROXY/HTTP_PROXY 环境变量,设置全局 fetch dispatcher
3
+ * 在入口文件最先导入,确保所有 fetch 调用都走代理
4
+ */
5
+
6
+ const proxyUrl = process.env.HTTPS_PROXY || process.env.https_proxy
7
+ || process.env.HTTP_PROXY || process.env.http_proxy;
8
+
9
+ if (proxyUrl) {
10
+ try {
11
+ // Node.js 22+ 内置 undici ProxyAgent
12
+ // @ts-ignore — undici 内置于 Node.js 22+ 但无独立类型声明
13
+ const { ProxyAgent, setGlobalDispatcher } = await import('undici');
14
+ setGlobalDispatcher(new ProxyAgent(proxyUrl));
15
+ process.stderr.write(`[wechat-channel] 使用代理: ${proxyUrl}\n`);
16
+ } catch {
17
+ process.stderr.write(`[wechat-channel] 警告: 设置代理失败,将直连\n`);
18
+ }
19
+ }