@lightcone-ai/daemon 0.15.19 → 0.15.21

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.
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { randomUUID } from 'crypto';
3
3
  import { spawn } from 'child_process';
4
- import { accessSync, constants as fsConstants } from 'fs';
4
+ import { accessSync, constants as fsConstants, existsSync, readFileSync, rmSync } from 'fs';
5
5
  import http from 'http';
6
6
  import net from 'net';
7
+ import path from 'path';
7
8
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
8
9
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
9
10
  import { z } from 'zod';
@@ -86,6 +87,12 @@ class CdpSession {
86
87
  if (!profileDir) throw new Error('LOGIN_REQUIRED:WECHAT_MP_PROFILE_DIR is not configured');
87
88
  const chrome = detectChrome();
88
89
  this._port = await getFreePort();
90
+
91
+ for (const lockFile of ['SingletonLock', 'SingletonCookie', 'SingletonSocket']) {
92
+ const lockPath = path.join(profileDir, lockFile);
93
+ try { if (existsSync(lockPath)) rmSync(lockPath, { force: true }); } catch {}
94
+ }
95
+
89
96
  this._proc = spawn(chrome, [
90
97
  `--remote-debugging-port=${this._port}`,
91
98
  '--no-sandbox',
@@ -96,7 +103,7 @@ class CdpSession {
96
103
  '--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
97
104
  `--user-data-dir=${profileDir}`,
98
105
  '--window-size=1280,900',
99
- `${WECHAT_MP_ORIGIN}/cgi-bin/home?t=home/index&lang=zh_CN`,
106
+ 'about:blank',
100
107
  ], { stdio: 'ignore' });
101
108
 
102
109
  for (let i = 0; i < 50; i += 1) {
@@ -112,6 +119,8 @@ class CdpSession {
112
119
  await this.cdp('Page.enable');
113
120
  await this.cdp('Network.enable');
114
121
  await this.cdp('Runtime.enable');
122
+ await this.injectCookies(profileDir);
123
+ await this.navigate(`${WECHAT_MP_ORIGIN}/cgi-bin/home?t=home/index&lang=zh_CN`);
115
124
  }
116
125
 
117
126
  _connectWs(wsUrl) {
@@ -160,6 +169,42 @@ class CdpSession {
160
169
  await sleep(1500);
161
170
  }
162
171
 
172
+ async injectCookies(profileDir) {
173
+ const cookiesFile = path.join(profileDir, 'cookies.json');
174
+ if (!existsSync(cookiesFile)) {
175
+ console.error(`[wechat-mp-fetch] cookies.json not found at ${cookiesFile}`);
176
+ return;
177
+ }
178
+ try {
179
+ const rawCookies = JSON.parse(readFileSync(cookiesFile, 'utf8'));
180
+ const cookies = rawCookies.map(({
181
+ name,
182
+ value,
183
+ domain,
184
+ path: cookiePath,
185
+ secure,
186
+ httpOnly,
187
+ sameSite,
188
+ expires,
189
+ priority,
190
+ }) => {
191
+ const cookie = { name, value };
192
+ if (domain !== undefined) cookie.domain = domain;
193
+ if (cookiePath !== undefined) cookie.path = cookiePath;
194
+ if (secure !== undefined) cookie.secure = secure;
195
+ if (httpOnly !== undefined) cookie.httpOnly = httpOnly;
196
+ if (sameSite !== undefined) cookie.sameSite = sameSite;
197
+ if (expires !== undefined && expires !== -1) cookie.expires = expires;
198
+ if (priority !== undefined) cookie.priority = priority;
199
+ return cookie;
200
+ });
201
+ await this.cdp('Network.setCookies', { cookies });
202
+ console.error(`[wechat-mp-fetch] Injected ${cookies.length} cookies from cookies.json`);
203
+ } catch (error) {
204
+ console.error(`[wechat-mp-fetch] Failed to inject cookies: ${error?.message ?? error}`);
205
+ }
206
+ }
207
+
163
208
  async evalValue(expression) {
164
209
  const result = await this.cdp('Runtime.evaluate', {
165
210
  expression,
@@ -191,7 +236,13 @@ async function ensureLoggedIn() {
191
236
  await cdp.navigate(`${WECHAT_MP_ORIGIN}/cgi-bin/home?t=home/index&lang=zh_CN`);
192
237
  href = await cdp.currentUrl();
193
238
  }
194
- const token = new URL(String(href)).searchParams.get('token') ?? '';
239
+ let token = '';
240
+ for (let i = 0; i < 12; i += 1) {
241
+ href = await cdp.currentUrl().catch(() => href);
242
+ token = new URL(String(href)).searchParams.get('token') ?? '';
243
+ if (token) break;
244
+ await sleep(500);
245
+ }
195
246
  if (!token) {
196
247
  throw new Error('LOGIN_REQUIRED:WeChat MP backend login is required');
197
248
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightcone-ai/daemon",
3
- "version": "0.15.19",
3
+ "version": "0.15.21",
4
4
  "type": "module",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -104,6 +104,22 @@ export const PLATFORM_CONFIGS = {
104
104
  ?? null;
105
105
  return val !== null && val !== baseline;
106
106
  },
107
+ async isPageLoggedIn(session) {
108
+ const result = await session.send('Runtime.evaluate', {
109
+ expression: `(() => {
110
+ const href = location.href;
111
+ const text = document.body?.innerText || '';
112
+ return {
113
+ href,
114
+ hasToken: /[?&]token=\\d+/.test(href),
115
+ loginTimedOut: text.includes('登录超时') || text.includes('重新登录')
116
+ };
117
+ })()`,
118
+ returnByValue: true,
119
+ }, 5000);
120
+ const value = result?.result?.value ?? {};
121
+ return Boolean(value.hasToken) && !value.loginTimedOut;
122
+ },
107
123
  },
108
124
  };
109
125
 
@@ -400,7 +416,12 @@ export class BrowserLoginSession {
400
416
 
401
417
  async isLoggedIn(baseline) {
402
418
  const result = await this.send('Network.getAllCookies', {});
403
- return this._config.isLoggedIn(result.cookies ?? [], baseline);
419
+ const cookieLoggedIn = this._config.isLoggedIn(result.cookies ?? [], baseline);
420
+ if (!cookieLoggedIn) return false;
421
+ if (typeof this._config.isPageLoggedIn === 'function') {
422
+ return this._config.isPageLoggedIn(this);
423
+ }
424
+ return true;
404
425
  }
405
426
 
406
427
  _startPolling(connection, baselineSession) {