@lightcone-ai/daemon 0.9.32 → 0.9.34

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.
@@ -3,8 +3,9 @@
3
3
  * Manages one Chrome process per platform, reusing CDP connections
4
4
  * across tool calls rather than restarting Chrome each time.
5
5
  */
6
- import { spawn } from 'child_process';
7
- import { accessSync, constants as fsConstants } from 'fs';
6
+ import { spawn, execSync } from 'child_process';
7
+ import { accessSync, constants as fsConstants, rmSync, existsSync } from 'fs';
8
+ import path from 'path';
8
9
  import http from 'http';
9
10
  import { WebSocket } from 'ws';
10
11
 
@@ -107,15 +108,30 @@ async function _connectCdp(port) {
107
108
  }
108
109
 
109
110
  async function _spawnChrome(profileDir, port) {
111
+ // Clean up stale lock files
112
+ for (const lockFile of ['SingletonLock', 'SingletonCookie', 'SingletonSocket']) {
113
+ const p = path.join(profileDir, lockFile);
114
+ try { if (existsSync(p)) rmSync(p, { force: true }); } catch {}
115
+ }
116
+ // Kill any process holding the port
117
+ try {
118
+ if (process.platform !== 'win32') {
119
+ execSync(`lsof -ti:${port} | xargs kill -9`, { stdio: 'ignore' });
120
+ }
121
+ } catch {}
122
+
110
123
  const proc = spawn(CHROME_BIN, [
111
124
  `--remote-debugging-port=${port}`,
112
125
  '--no-sandbox',
113
126
  '--disable-dev-shm-usage',
114
- '--headless=false',
127
+ '--headless=new',
115
128
  `--user-data-dir=${profileDir}`,
116
129
  '--window-size=1280,900',
117
130
  '--disable-blink-features=AutomationControlled',
118
131
  '--disable-infobars',
132
+ '--no-first-run',
133
+ '--no-default-browser-check',
134
+ '--disable-hang-monitor',
119
135
  '--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',
120
136
  'about:blank',
121
137
  ], { stdio: 'ignore', detached: false });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightcone-ai/daemon",
3
- "version": "0.9.32",
3
+ "version": "0.9.34",
4
4
  "type": "module",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -4,9 +4,9 @@
4
4
  * Runs on the daemon machine where Chrome is installed.
5
5
  * Screenshots are sent back to server via daemon WebSocket.
6
6
  */
7
- import { spawn } from 'child_process';
7
+ import { spawn, execSync } from 'child_process';
8
8
  import { homedir } from 'os';
9
- import { accessSync, constants as fsConstants } from 'fs';
9
+ import { accessSync, constants as fsConstants, rmSync, existsSync } from 'fs';
10
10
  import path from 'path';
11
11
  import http from 'http';
12
12
  import { WebSocket } from 'ws';
@@ -94,18 +94,39 @@ export class BrowserLoginSession {
94
94
  async start(connection, userId) {
95
95
  this._profileDir = profileDir(this._platform, userId);
96
96
 
97
+ // Clean up stale Chrome lock files that prevent reuse of the profile dir
98
+ for (const lockFile of ['SingletonLock', 'SingletonCookie', 'SingletonSocket']) {
99
+ const p = path.join(this._profileDir, lockFile);
100
+ try { if (existsSync(p)) rmSync(p, { force: true }); } catch {}
101
+ }
102
+
103
+ // Kill any process already holding CDP_PORT
104
+ try {
105
+ if (process.platform !== 'win32') {
106
+ execSync(`lsof -ti:${CDP_PORT} | xargs kill -9`, { stdio: 'ignore' });
107
+ }
108
+ } catch {}
109
+
97
110
  this._proc = spawn(CHROME_BIN, [
98
111
  `--remote-debugging-port=${CDP_PORT}`,
99
112
  '--no-sandbox',
100
113
  '--disable-dev-shm-usage',
101
- '--headless=false',
114
+ '--headless=new',
102
115
  `--user-data-dir=${this._profileDir}`,
103
116
  '--window-size=800,900',
104
117
  '--disable-blink-features=AutomationControlled',
105
118
  '--disable-infobars',
119
+ '--no-first-run',
120
+ '--no-default-browser-check',
121
+ '--disable-hang-monitor',
106
122
  '--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',
107
123
  'about:blank',
108
- ], { stdio: 'ignore', detached: false });
124
+ ], { stdio: ['ignore', 'ignore', 'pipe'], detached: false });
125
+
126
+ this._proc.stderr.on('data', (data) => {
127
+ const text = data.toString().trim();
128
+ if (text) console.error(`[BrowserLogin][${this._platform}] Chrome stderr: ${text.slice(0, 300)}`);
129
+ });
109
130
 
110
131
  this._proc.on('error', (err) => {
111
132
  console.error(`[BrowserLogin][${this._platform}] Chrome spawn error: ${err.message}`);
@@ -113,8 +134,8 @@ export class BrowserLoginSession {
113
134
  connection.send({ type: 'browser:login_error', platform: this._platform, error: `Chrome 启动失败: ${err.message}` });
114
135
  });
115
136
 
116
- this._proc.on('exit', (code) => {
117
- console.log(`[BrowserLogin][${this._platform}] Chrome exited (code=${code})`);
137
+ this._proc.on('exit', (code, signal) => {
138
+ console.log(`[BrowserLogin][${this._platform}] Chrome exited (code=${code} signal=${signal})`);
118
139
  this._stopTimers();
119
140
  });
120
141