@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(`${WECHAT_MP_ORIGIN}/cgi-bin/home?t=home/index&lang=zh_CN`);
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(`${WECHAT_MP_ORIGIN}/cgi-bin/home?t=home/index&lang=zh_CN`);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightcone-ai/daemon",
3
- "version": "0.15.22",
3
+ "version": "0.15.24",
4
4
  "type": "module",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -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 cookies: ${err.message}`);
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] ?? process.env[envKey] ?? '';
114
+ resolvedEnv[envKey] = agentEnv[envKey] || process.env[envKey] || '';
115
115
  }
116
116
 
117
117
  if (mcpServers[mc.server]) {