chatccc 0.2.107 → 0.2.109
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/package.json +1 -1
- package/src/__tests__/config-reload.test.ts +2 -1
- package/src/config.ts +2 -2
- package/src/index.ts +25 -5
- package/src/wechat-platform.ts +24 -13
package/package.json
CHANGED
|
@@ -131,7 +131,8 @@ describe("applyLoadedConfig — 刷新 export let 常量", () => {
|
|
|
131
131
|
cursor: { enabled: true, defaultAgent: false, path: "/x/cursor", model: "claude-3.7-sonnet" },
|
|
132
132
|
});
|
|
133
133
|
|
|
134
|
-
// CURSOR_AGENT_ARGS 是 ['-p', '--force', ..., '--model', 'claude-3.7-sonnet']
|
|
134
|
+
// CURSOR_AGENT_ARGS 是 ['-p', '--force', '--approve-mcps', ..., '--model', 'claude-3.7-sonnet']
|
|
135
|
+
expect(CURSOR_AGENT_ARGS).toContain("--approve-mcps");
|
|
135
136
|
expect(CURSOR_AGENT_ARGS).toContain("--model");
|
|
136
137
|
expect(CURSOR_AGENT_ARGS).toContain("claude-3.7-sonnet");
|
|
137
138
|
});
|
package/src/config.ts
CHANGED
|
@@ -555,7 +555,7 @@ function detectCursorAgent(): string {
|
|
|
555
555
|
export let CURSOR_AGENT_COMMAND = detectCursorAgent();
|
|
556
556
|
|
|
557
557
|
function resolveCursorAgentArgs(): string[] {
|
|
558
|
-
let args = "-p --force --output-format stream-json --stream-partial-output";
|
|
558
|
+
let args = "-p --force --approve-mcps --output-format stream-json --stream-partial-output";
|
|
559
559
|
const model = config.cursor.model;
|
|
560
560
|
if (model.trim() !== "") {
|
|
561
561
|
args += ` --model ${model}`;
|
|
@@ -563,7 +563,7 @@ function resolveCursorAgentArgs(): string[] {
|
|
|
563
563
|
return args.split(/\s+/).filter(Boolean);
|
|
564
564
|
}
|
|
565
565
|
|
|
566
|
-
/** Cursor agent 参数:-p 非交互模式,--force
|
|
566
|
+
/** Cursor agent 参数:-p 非交互模式,--force 强制允许命令,--approve-mcps 自动批准 MCP,stream-json 流式 JSONL 输出 */
|
|
567
567
|
export let CURSOR_AGENT_ARGS = resolveCursorAgentArgs();
|
|
568
568
|
|
|
569
569
|
// ---------------------------------------------------------------------------
|
package/src/index.ts
CHANGED
|
@@ -660,8 +660,11 @@ async function startWechatSupervisor(): Promise<void> {
|
|
|
660
660
|
console.log("\n[WX] 启动微信 iLink 平台...");
|
|
661
661
|
|
|
662
662
|
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
|
|
663
|
+
const MAX_QR_RETRIES = 3;
|
|
664
|
+
let qrTimeoutCount = 0;
|
|
663
665
|
|
|
664
666
|
while (!wechatSignal.stopped) {
|
|
667
|
+
let isQrTimeout = false;
|
|
665
668
|
try {
|
|
666
669
|
await startWechatPlatform(
|
|
667
670
|
(text, chatId, openId, msgTimestamp, chatType, traceId) =>
|
|
@@ -669,14 +672,31 @@ async function startWechatSupervisor(): Promise<void> {
|
|
|
669
672
|
wechatSignal,
|
|
670
673
|
ILINK_REUSE_TOKEN_ON_START,
|
|
671
674
|
);
|
|
675
|
+
// 登录成功后重置计数
|
|
676
|
+
qrTimeoutCount = 0;
|
|
672
677
|
} catch (err) {
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
)
|
|
678
|
+
const msg = (err as Error).message ?? "";
|
|
679
|
+
isQrTimeout = msg.includes("QR 登录超时");
|
|
680
|
+
if (isQrTimeout) {
|
|
681
|
+
qrTimeoutCount++;
|
|
682
|
+
console.error(
|
|
683
|
+
`[WX] QR 登录超时 (${qrTimeoutCount}/${MAX_QR_RETRIES}): ${msg}`,
|
|
684
|
+
);
|
|
685
|
+
if (qrTimeoutCount >= MAX_QR_RETRIES) {
|
|
686
|
+
console.error(
|
|
687
|
+
`[WX] 已连续 ${MAX_QR_RETRIES} 次 QR 登录超时,放弃重试。如需重新尝试请重启 ChatCCC。`,
|
|
688
|
+
);
|
|
689
|
+
break;
|
|
690
|
+
}
|
|
691
|
+
} else {
|
|
692
|
+
console.error(`[WX] 微信 iLink 崩溃: ${msg}`);
|
|
693
|
+
}
|
|
676
694
|
}
|
|
677
695
|
if (wechatSignal.stopped) break;
|
|
678
|
-
|
|
679
|
-
|
|
696
|
+
const delaySeconds = isQrTimeout ? 300 : 30;
|
|
697
|
+
const delayDesc = isQrTimeout ? "5 分钟" : "30 秒";
|
|
698
|
+
console.log(`[WX] ${delayDesc}后重试...`);
|
|
699
|
+
await sleep(delaySeconds * 1000);
|
|
680
700
|
}
|
|
681
701
|
console.log("[WX] 微信 iLink 平台已停止。");
|
|
682
702
|
}
|
package/src/wechat-platform.ts
CHANGED
|
@@ -429,23 +429,34 @@ export async function startWechatPlatform(
|
|
|
429
429
|
}
|
|
430
430
|
}
|
|
431
431
|
|
|
432
|
-
// 请求新 QR
|
|
433
|
-
|
|
432
|
+
// 请求新 QR(5 分钟内未扫码则放弃本轮,由 supervisor 稍后重试)
|
|
433
|
+
const QR_LOGIN_TIMEOUT_MS = 5 * 60 * 1000;
|
|
434
|
+
platformLog("启动微信 iLink QR 登录(5 分钟内未扫码将自动重试)...");
|
|
434
435
|
ilinkWire = new OpenIlinkWire("", {
|
|
435
436
|
base_url: saved.baseUrl,
|
|
436
437
|
});
|
|
437
438
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
439
|
+
let qrExpiredCount = 0;
|
|
440
|
+
const loginResult = await Promise.race([
|
|
441
|
+
ilinkWire.loginWithQr({
|
|
442
|
+
on_qrcode: (content) => {
|
|
443
|
+
printScanMaterial(content);
|
|
444
|
+
},
|
|
445
|
+
on_scanned: () => {
|
|
446
|
+
platformLog("QR 已扫描,请在微信中确认登录。");
|
|
447
|
+
},
|
|
448
|
+
on_expired: (attempt, maxAttempts) => {
|
|
449
|
+
qrExpiredCount++;
|
|
450
|
+
platformLog(`QR 已过期,正在刷新 (${attempt}/${maxAttempts})。`);
|
|
451
|
+
},
|
|
452
|
+
}),
|
|
453
|
+
new Promise<never>((_, reject) =>
|
|
454
|
+
setTimeout(
|
|
455
|
+
() => reject(new Error(`QR 登录超时(${QR_LOGIN_TIMEOUT_MS / 60000} 分钟内未扫码,已刷新 ${qrExpiredCount} 次)`)),
|
|
456
|
+
QR_LOGIN_TIMEOUT_MS,
|
|
457
|
+
),
|
|
458
|
+
),
|
|
459
|
+
]);
|
|
449
460
|
|
|
450
461
|
if (!loginResult.connected) {
|
|
451
462
|
throw new Error(`微信 iLink QR 登录失败: ${loginResult.message}`);
|