@lightcone-ai/daemon 0.9.38 → 0.9.40

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightcone-ai/daemon",
3
- "version": "0.9.38",
3
+ "version": "0.9.40",
4
4
  "type": "module",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { spawn, execSync } from 'child_process';
8
8
  import { homedir } from 'os';
9
- import { accessSync, constants as fsConstants, rmSync, existsSync } from 'fs';
9
+ import { accessSync, constants as fsConstants, rmSync, existsSync, mkdirSync } from 'fs';
10
10
  import path from 'path';
11
11
  import http from 'http';
12
12
  import { WebSocket } from 'ws';
@@ -17,18 +17,27 @@ export const PLATFORM_CONFIGS = {
17
17
  xhs: {
18
18
  loginUrl: 'https://www.xiaohongshu.com',
19
19
  isLoggedIn: (cookies) => cookies.some(c => c.name === 'web_session' && c.value?.length > 0),
20
+ sessionCookies: [{ name: 'web_session', domain: '.xiaohongshu.com' }],
20
21
  },
21
22
  douyin: {
22
23
  loginUrl: 'https://www.douyin.com',
23
24
  isLoggedIn: (cookies) => cookies.some(c =>
24
25
  (c.name === 'sessionid' || c.name === 'sid_guard') && c.value?.length > 0
25
26
  ),
27
+ sessionCookies: [
28
+ { name: 'sessionid', domain: '.douyin.com' },
29
+ { name: 'sid_guard', domain: '.douyin.com' },
30
+ ],
26
31
  },
27
32
  kuaishou: {
28
33
  loginUrl: 'https://www.kuaishou.com',
29
34
  isLoggedIn: (cookies) => cookies.some(c =>
30
35
  (c.name === 'userId' || c.name === 'passToken') && c.value?.length > 0
31
36
  ),
37
+ sessionCookies: [
38
+ { name: 'userId', domain: '.kuaishou.com' },
39
+ { name: 'passToken', domain: '.kuaishou.com' },
40
+ ],
32
41
  },
33
42
  };
34
43
 
@@ -94,6 +103,23 @@ export class BrowserLoginSession {
94
103
  async start(connection, userId) {
95
104
  this._profileDir = profileDir(this._platform, userId);
96
105
 
106
+ // Ensure profile dir exists
107
+ try { mkdirSync(this._profileDir, { recursive: true }); } catch {}
108
+
109
+ // Kill any process holding the CDP port
110
+ try {
111
+ if (process.platform !== 'win32') {
112
+ execSync(`lsof -ti:${CDP_PORT} | xargs kill -9`, { stdio: 'ignore' });
113
+ }
114
+ } catch {}
115
+ await sleep(300);
116
+
117
+ // Clean up stale Chrome lock files
118
+ for (const lockFile of ['SingletonLock', 'SingletonCookie', 'SingletonSocket']) {
119
+ const p = path.join(this._profileDir, lockFile);
120
+ try { if (existsSync(p)) rmSync(p, { force: true }); } catch {}
121
+ }
122
+
97
123
  this._proc = spawn(CHROME_BIN, [
98
124
  `--remote-debugging-port=${CDP_PORT}`,
99
125
  '--no-sandbox',
@@ -142,6 +168,10 @@ export class BrowserLoginSession {
142
168
  await this.send('Page.addScriptToEvaluateOnNewDocument', {
143
169
  source: `Object.defineProperty(navigator, 'webdriver', { get: () => undefined });`,
144
170
  });
171
+
172
+ // Clear the session cookie so we only detect a *fresh* login, not stale cached cookies
173
+ await this._clearSessionCookies();
174
+
145
175
  await this.send('Page.navigate', { url: this._config.loginUrl });
146
176
 
147
177
  this._startPolling(connection);
@@ -222,6 +252,15 @@ export class BrowserLoginSession {
222
252
  }, LOGIN_CHECK_INTERVAL_MS);
223
253
  }
224
254
 
255
+ async _clearSessionCookies() {
256
+ const cookies = this._config.sessionCookies ?? [];
257
+ for (const { name, domain } of cookies) {
258
+ try {
259
+ await this.send('Network.deleteCookies', { name, domain });
260
+ } catch {}
261
+ }
262
+ }
263
+
225
264
  _stopTimers() {
226
265
  if (this._screenshotTimer) { clearInterval(this._screenshotTimer); this._screenshotTimer = null; }
227
266
  if (this._loginCheckTimer) { clearInterval(this._loginCheckTimer); this._loginCheckTimer = null; }