wechat-to-anything 0.6.8 → 0.6.10
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/.claude/settings.local.json +3 -1
- package/cli/agent-adapter.mjs +17 -14
- package/cli/bridge.mjs +4 -3
- package/cli/weixin.mjs +1 -1
- package/package.json +2 -1
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
"Bash(find /Users/zxw/AITOOL/wechat-to-anything/examples -name *.mjs ! -path */node_modules/* -exec head -40 {})",
|
|
6
6
|
"Bash(2)",
|
|
7
7
|
"Bash(ls -la /Users/zxw/AITOOL/wechat-to-anything/examples/*/package.json)",
|
|
8
|
-
"mcp__filesystem__read_text_file"
|
|
8
|
+
"mcp__filesystem__read_text_file",
|
|
9
|
+
"Bash(gh issue:*)",
|
|
10
|
+
"Bash(gh api:*)"
|
|
9
11
|
]
|
|
10
12
|
}
|
|
11
13
|
}
|
package/cli/agent-adapter.mjs
CHANGED
|
@@ -8,14 +8,12 @@
|
|
|
8
8
|
* - cli://gemini → 内置 Gemini CLI 适配器
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { execFile
|
|
11
|
+
import { execFile } from "node:child_process";
|
|
12
12
|
import { writeFile, readFile, unlink, mkdir } from "node:fs/promises";
|
|
13
13
|
import { join } from "node:path";
|
|
14
14
|
import { tmpdir } from "node:os";
|
|
15
15
|
import { randomBytes } from "node:crypto";
|
|
16
|
-
|
|
17
|
-
// Windows 上 npm 全局安装生成 .cmd,execFile/spawn 需要 shell: true 才能找到
|
|
18
|
-
const IS_WIN = process.platform === "win32";
|
|
16
|
+
import crossSpawn from "cross-spawn";
|
|
19
17
|
|
|
20
18
|
/**
|
|
21
19
|
* 统一调用接口 — 根据 URL 自动选择适配器
|
|
@@ -40,8 +38,12 @@ export async function checkAgent(url) {
|
|
|
40
38
|
const name = url.replace("cli://", "");
|
|
41
39
|
const cmd = { codex: "codex", gemini: "gemini", claude: "claude", openclaw: "openclaw" }[name] || name;
|
|
42
40
|
return new Promise((resolve, reject) => {
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
const child = crossSpawn(cmd, ["--version"], { timeout: 5000 });
|
|
42
|
+
child.on("error", (err) => reject(new Error(`${cmd} CLI 未安装(npm install -g ${{
|
|
43
|
+
codex: "@openai/codex", gemini: "@google/gemini-cli", claude: "@anthropic-ai/claude-code", openclaw: "openclaw"
|
|
44
|
+
}[name] || cmd})`)));
|
|
45
|
+
child.on("close", (code) => {
|
|
46
|
+
if (code !== 0) reject(new Error(`${cmd} CLI 未安装(npm install -g ${{
|
|
45
47
|
codex: "@openai/codex", gemini: "@google/gemini-cli", claude: "@anthropic-ai/claude-code", openclaw: "openclaw"
|
|
46
48
|
}[name] || cmd})`));
|
|
47
49
|
else resolve();
|
|
@@ -164,23 +166,26 @@ function runCodex(prompt, imagePaths = []) {
|
|
|
164
166
|
for (const img of imagePaths) args.push("-i", img);
|
|
165
167
|
args.push("--", prompt);
|
|
166
168
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
+
const child = crossSpawn("codex", args, { timeout: 300_000, cwd: tmpdir() });
|
|
170
|
+
let stdout = "", stderr = "";
|
|
171
|
+
child.stdout.on("data", (d) => (stdout += d));
|
|
172
|
+
child.stderr.on("data", (d) => (stderr += d));
|
|
173
|
+
child.on("close", async () => {
|
|
169
174
|
try {
|
|
170
175
|
const reply = await readFile(outFile, "utf-8").catch(() => "");
|
|
171
176
|
await unlink(outFile).catch(() => {});
|
|
172
177
|
if (reply.trim()) resolve(reply.trim());
|
|
173
178
|
else if (stdout.trim()) resolve(stdout.trim());
|
|
174
|
-
else
|
|
175
|
-
else resolve("(empty response)");
|
|
179
|
+
else reject(new Error((stderr || "empty response").trim().slice(0, 300)));
|
|
176
180
|
} catch (e) { reject(e); }
|
|
177
181
|
});
|
|
182
|
+
child.on("error", (err) => reject(err));
|
|
178
183
|
});
|
|
179
184
|
}
|
|
180
185
|
|
|
181
186
|
function runGemini(prompt) {
|
|
182
187
|
return new Promise((resolve, reject) => {
|
|
183
|
-
const child =
|
|
188
|
+
const child = crossSpawn("gemini", [], { cwd: tmpdir(), stdio: ["pipe", "pipe", "pipe"], timeout: 300_000 });
|
|
184
189
|
let stdout = "", stderr = "";
|
|
185
190
|
child.stdout.on("data", (d) => (stdout += d));
|
|
186
191
|
child.stderr.on("data", (d) => (stderr += d));
|
|
@@ -197,10 +202,9 @@ function runGemini(prompt) {
|
|
|
197
202
|
|
|
198
203
|
function runClaude(prompt) {
|
|
199
204
|
return new Promise((resolve, reject) => {
|
|
200
|
-
const child =
|
|
205
|
+
const child = crossSpawn("claude", ["--print", prompt], {
|
|
201
206
|
stdio: ["ignore", "pipe", "pipe"],
|
|
202
207
|
timeout: 300_000,
|
|
203
|
-
shell: IS_WIN,
|
|
204
208
|
});
|
|
205
209
|
let stdout = "", stderr = "";
|
|
206
210
|
child.stdout.on("data", (d) => (stdout += d));
|
|
@@ -222,7 +226,6 @@ function runOpenClaw(prompt) {
|
|
|
222
226
|
cwd: tmpdir(),
|
|
223
227
|
stdio: ["ignore", "pipe", "pipe"],
|
|
224
228
|
timeout: 300_000,
|
|
225
|
-
shell: IS_WIN,
|
|
226
229
|
});
|
|
227
230
|
let stdout = "", stderr = "";
|
|
228
231
|
child.stdout.on("data", (d) => (stdout += d));
|
package/cli/bridge.mjs
CHANGED
|
@@ -30,18 +30,19 @@ export async function start(agents, defaultAgent, { port = 9099 } = {}) {
|
|
|
30
30
|
if (!creds) {
|
|
31
31
|
console.log(pc.yellow("📱 首次使用,请扫码登录微信\n"));
|
|
32
32
|
try {
|
|
33
|
-
creds = await loginWithQR(async (
|
|
33
|
+
creds = await loginWithQR(async (qrToken, qrImgUrl) => {
|
|
34
34
|
try {
|
|
35
35
|
const qrt = await import("qrcode-terminal");
|
|
36
36
|
await new Promise((resolve) => {
|
|
37
|
-
qrt.default.generate(
|
|
37
|
+
qrt.default.generate(qrToken, { small: true }, (qr) => {
|
|
38
38
|
console.log(qr);
|
|
39
39
|
resolve();
|
|
40
40
|
});
|
|
41
41
|
});
|
|
42
42
|
} catch {
|
|
43
|
-
|
|
43
|
+
// qrcode-terminal 不可用时 fallback
|
|
44
44
|
}
|
|
45
|
+
console.log(pc.dim(` 浏览器扫码备用: ${qrImgUrl}`));
|
|
45
46
|
});
|
|
46
47
|
console.log(pc.green("✅ 微信登录成功!"));
|
|
47
48
|
} catch (err) {
|
package/cli/weixin.mjs
CHANGED
|
@@ -82,7 +82,7 @@ export async function pollQRStatus(qrcode) {
|
|
|
82
82
|
*/
|
|
83
83
|
export async function loginWithQR(onQrCode) {
|
|
84
84
|
const qr = await getQRCode();
|
|
85
|
-
await onQrCode(qr.qrcode_img_content);
|
|
85
|
+
await onQrCode(qr.qrcode, qr.qrcode_img_content);
|
|
86
86
|
|
|
87
87
|
const deadline = Date.now() + 5 * 60_000; // 5 min
|
|
88
88
|
while (Date.now() < deadline) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wechat-to-anything",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.10",
|
|
4
4
|
"description": "一条命令,把微信变成任何 AI Agent 的入口",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"node": ">=22"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
+
"cross-spawn": "^7.0.6",
|
|
36
37
|
"picocolors": "^1.1.0",
|
|
37
38
|
"qrcode-terminal": "^0.12.0"
|
|
38
39
|
}
|