@lightcone-ai/daemon 0.15.22 → 0.15.24
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.
|
@@ -36,6 +36,20 @@ const cache = new Map();
|
|
|
36
36
|
let lastRequestAt = 0;
|
|
37
37
|
let session = null;
|
|
38
38
|
|
|
39
|
+
function readSavedSession(profileDir) {
|
|
40
|
+
const sessionFile = path.join(profileDir, 'session.json');
|
|
41
|
+
if (!existsSync(sessionFile)) {
|
|
42
|
+
throw new Error('LOGIN_REQUIRED:WeChat MP backend session token is missing; please scan login again');
|
|
43
|
+
}
|
|
44
|
+
const saved = parseJsonMaybe(readFileSync(sessionFile, 'utf8'));
|
|
45
|
+
const token = String(saved?.token ?? '').trim();
|
|
46
|
+
const homeUrl = String(saved?.homeUrl ?? '').trim();
|
|
47
|
+
if (!token || !homeUrl.startsWith(`${WECHAT_MP_ORIGIN}/cgi-bin/`)) {
|
|
48
|
+
throw new Error('LOGIN_REQUIRED:WeChat MP backend session token is invalid; please scan login again');
|
|
49
|
+
}
|
|
50
|
+
return { token, homeUrl, savedAt: saved?.savedAt ?? null };
|
|
51
|
+
}
|
|
52
|
+
|
|
39
53
|
function detectChrome() {
|
|
40
54
|
if (process.env.CHROME_BIN) return process.env.CHROME_BIN;
|
|
41
55
|
const candidates = [
|
|
@@ -85,6 +99,7 @@ class CdpSession {
|
|
|
85
99
|
|
|
86
100
|
async launch(profileDir) {
|
|
87
101
|
if (!profileDir) throw new Error('LOGIN_REQUIRED:WECHAT_MP_PROFILE_DIR is not configured');
|
|
102
|
+
const savedSession = readSavedSession(profileDir);
|
|
88
103
|
const chrome = detectChrome();
|
|
89
104
|
this._port = await getFreePort();
|
|
90
105
|
|
|
@@ -120,7 +135,7 @@ class CdpSession {
|
|
|
120
135
|
await this.cdp('Network.enable');
|
|
121
136
|
await this.cdp('Runtime.enable');
|
|
122
137
|
await this.injectCookies(profileDir);
|
|
123
|
-
await this.navigate(
|
|
138
|
+
await this.navigate(savedSession.homeUrl);
|
|
124
139
|
}
|
|
125
140
|
|
|
126
141
|
_connectWs(wsUrl) {
|
|
@@ -220,6 +235,19 @@ class CdpSession {
|
|
|
220
235
|
async currentUrl() {
|
|
221
236
|
return this.evalValue('location.href');
|
|
222
237
|
}
|
|
238
|
+
|
|
239
|
+
async close() {
|
|
240
|
+
try { await this.cdp('Browser.close', {}, 3000); } catch {}
|
|
241
|
+
await sleep(300);
|
|
242
|
+
if (this._ws) {
|
|
243
|
+
try { this._ws.close(); } catch {}
|
|
244
|
+
this._ws = null;
|
|
245
|
+
}
|
|
246
|
+
if (this._proc) {
|
|
247
|
+
try { this._proc.kill('SIGKILL'); } catch {}
|
|
248
|
+
this._proc = null;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
223
251
|
}
|
|
224
252
|
|
|
225
253
|
async function getSession() {
|
|
@@ -229,23 +257,40 @@ async function getSession() {
|
|
|
229
257
|
return session;
|
|
230
258
|
}
|
|
231
259
|
|
|
260
|
+
async function closeSession() {
|
|
261
|
+
const active = session;
|
|
262
|
+
session = null;
|
|
263
|
+
if (active) await active.close();
|
|
264
|
+
}
|
|
265
|
+
|
|
232
266
|
async function ensureLoggedIn() {
|
|
233
267
|
const cdp = await getSession();
|
|
268
|
+
const savedSession = readSavedSession(WECHAT_MP_PROFILE_DIR);
|
|
234
269
|
let href = await cdp.currentUrl().catch(() => '');
|
|
235
270
|
if (!String(href).startsWith(WECHAT_MP_ORIGIN)) {
|
|
236
|
-
await cdp.navigate(
|
|
271
|
+
await cdp.navigate(savedSession.homeUrl);
|
|
237
272
|
href = await cdp.currentUrl();
|
|
238
273
|
}
|
|
239
|
-
let token =
|
|
274
|
+
let token = savedSession.token;
|
|
240
275
|
for (let i = 0; i < 12; i += 1) {
|
|
241
276
|
href = await cdp.currentUrl().catch(() => href);
|
|
242
|
-
token = new URL(String(href)).searchParams.get('token') ??
|
|
277
|
+
token = new URL(String(href)).searchParams.get('token') ?? token;
|
|
243
278
|
if (token) break;
|
|
244
279
|
await sleep(500);
|
|
245
280
|
}
|
|
281
|
+
const pageState = await cdp.evalValue(`(() => {
|
|
282
|
+
const text = document.body?.innerText || '';
|
|
283
|
+
return {
|
|
284
|
+
href: location.href,
|
|
285
|
+
loginRequired: text.includes('登录超时') || text.includes('请重新登录') || text.includes('重新登录')
|
|
286
|
+
};
|
|
287
|
+
})()`).catch(() => null);
|
|
246
288
|
if (!token) {
|
|
247
289
|
throw new Error('LOGIN_REQUIRED:WeChat MP backend login is required');
|
|
248
290
|
}
|
|
291
|
+
if (pageState?.loginRequired) {
|
|
292
|
+
throw new Error('LOGIN_REQUIRED:WeChat MP backend session expired; please scan login again');
|
|
293
|
+
}
|
|
249
294
|
return { cdp, token };
|
|
250
295
|
}
|
|
251
296
|
|
|
@@ -461,6 +506,8 @@ server.tool(
|
|
|
461
506
|
return toolResult({ ok: true, logged_in: true, token_present: Boolean(token), source_type: 'wechat_mp' });
|
|
462
507
|
} catch (error) {
|
|
463
508
|
return toolError(error);
|
|
509
|
+
} finally {
|
|
510
|
+
await closeSession();
|
|
464
511
|
}
|
|
465
512
|
}
|
|
466
513
|
);
|
|
@@ -478,6 +525,8 @@ server.tool(
|
|
|
478
525
|
return toolResult(await searchAccounts(checked));
|
|
479
526
|
} catch (error) {
|
|
480
527
|
return toolError(error);
|
|
528
|
+
} finally {
|
|
529
|
+
await closeSession();
|
|
481
530
|
}
|
|
482
531
|
}
|
|
483
532
|
);
|
|
@@ -496,6 +545,8 @@ server.tool(
|
|
|
496
545
|
return toolResult(await listRecentArticles(checked));
|
|
497
546
|
} catch (error) {
|
|
498
547
|
return toolError(error);
|
|
548
|
+
} finally {
|
|
549
|
+
await closeSession();
|
|
499
550
|
}
|
|
500
551
|
}
|
|
501
552
|
);
|
|
@@ -519,3 +570,7 @@ server.tool(
|
|
|
519
570
|
const transport = new StdioServerTransport();
|
|
520
571
|
await server.connect(transport);
|
|
521
572
|
console.error('[wechat-mp-fetch] MCP Server started');
|
|
573
|
+
|
|
574
|
+
process.once('SIGINT', () => { closeSession().finally(() => process.exit(130)); });
|
|
575
|
+
process.once('SIGTERM', () => { closeSession().finally(() => process.exit(143)); });
|
|
576
|
+
process.once('beforeExit', () => { if (session) void closeSession(); });
|
package/package.json
CHANGED
package/src/browser-login.js
CHANGED
|
@@ -490,8 +490,25 @@ export class BrowserLoginSession {
|
|
|
490
490
|
);
|
|
491
491
|
writeFileSync(path.join(this._profileDir, 'cookies.json'), JSON.stringify(cookies));
|
|
492
492
|
console.log(`[BrowserLogin][${this._platform}] Saved ${cookies.length} cookies to cookies.json`);
|
|
493
|
+
if (this._platform === 'wechat_mp') {
|
|
494
|
+
const hrefResult = await this.send('Runtime.evaluate', {
|
|
495
|
+
expression: 'location.href',
|
|
496
|
+
returnByValue: true,
|
|
497
|
+
}, 5000);
|
|
498
|
+
const homeUrl = String(hrefResult?.result?.value ?? '');
|
|
499
|
+
const token = new URL(homeUrl).searchParams.get('token') ?? '';
|
|
500
|
+
if (!token) throw new Error('WeChat MP token missing from logged-in URL');
|
|
501
|
+
writeFileSync(path.join(this._profileDir, 'session.json'), JSON.stringify({
|
|
502
|
+
platform: this._platform,
|
|
503
|
+
token,
|
|
504
|
+
homeUrl,
|
|
505
|
+
savedAt: new Date().toISOString(),
|
|
506
|
+
}));
|
|
507
|
+
console.log(`[BrowserLogin][${this._platform}] Saved backend session token to session.json`);
|
|
508
|
+
}
|
|
493
509
|
} catch (err) {
|
|
494
|
-
console.error(`[BrowserLogin][${this._platform}] Failed to save
|
|
510
|
+
console.error(`[BrowserLogin][${this._platform}] Failed to save browser session: ${err.message}`);
|
|
511
|
+
if (this._platform === 'wechat_mp') throw err;
|
|
495
512
|
}
|
|
496
513
|
// Kill any stale chrome-pool session so the next publish job starts fresh with new cookies
|
|
497
514
|
try {
|
package/src/mcp-config.js
CHANGED
|
@@ -111,7 +111,7 @@ export function buildSkillMcpServers({
|
|
|
111
111
|
const resolvedArgs = (mc.args ?? []).map(arg => resolveSkillArg(arg, config));
|
|
112
112
|
const resolvedEnv = {};
|
|
113
113
|
for (const envKey of (mc.env ?? [])) {
|
|
114
|
-
resolvedEnv[envKey] = agentEnv[envKey]
|
|
114
|
+
resolvedEnv[envKey] = agentEnv[envKey] || process.env[envKey] || '';
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
if (mcpServers[mc.server]) {
|