yiyan-browser-agent 1.0.23 → 1.0.25

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": "yiyan-browser-agent",
3
- "version": "1.0.23",
3
+ "version": "1.0.25",
4
4
  "description": "AI coding agent powered by Yiyan (文心一言) via browser automation — no API key needed",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -23,11 +23,15 @@ class BrowserManager {
23
23
  // Try connect existing browser
24
24
  try {
25
25
  if (fs.existsSync(CDP_PORT_FILE)) {
26
- const portInfo = JSON.parse(fs.readFileSync(CDP_PORT_FILE, 'utf8'));
27
- const browserURL = `http://localhost:${portInfo.port || CDP_PORT}`;
26
+ const endpointInfo = JSON.parse(fs.readFileSync(CDP_PORT_FILE, 'utf8'));
27
+ const wsEndpoint = endpointInfo.wsEndpoint;
28
+
29
+ if (!wsEndpoint) {
30
+ throw new Error('No wsEndpoint in file');
31
+ }
28
32
 
29
33
  logger.info('Connecting to existing browser...');
30
- const browser = await chromium.connectOverCDP(browserURL, { timeout: 5000 });
34
+ const browser = await chromium.connect({ wsEndpoint, timeout: 5000 });
31
35
 
32
36
  // Create NEW context and page (tab) for this task
33
37
  const context = await browser.newContext({
@@ -54,25 +58,33 @@ class BrowserManager {
54
58
  * Launch new browser with CDP port
55
59
  */
56
60
  static async _launchNew() {
57
- logger.info('Launching new browser with CDP port ' + CDP_PORT + '...');
61
+ logger.info('Launching new browser server...');
58
62
 
59
- // Launch browser (not persistentContext) to expose CDP properly
60
- const browser = await chromium.launch({
63
+ // Use launchServer to create independent browser process
64
+ const browserServer = await chromium.launchServer({
61
65
  headless: false,
62
- port: CDP_PORT,
63
66
  args: [
64
67
  '--disable-blink-features=AutomationControlled',
65
68
  '--no-first-run',
66
69
  '--no-sandbox',
67
- `--user-data-dir=${SESSION_DIR}`,
68
70
  ],
69
71
  });
70
72
 
71
- // Save CDP port info
73
+ // Get the WebSocket endpoint
74
+ const wsEndpoint = browserServer.wsEndpoint();
75
+ logger.dim('WebSocket endpoint: ' + wsEndpoint);
76
+
77
+ // Save endpoint info IMMEDIATELY before any other operations
72
78
  fs.writeFileSync(CDP_PORT_FILE, JSON.stringify({
73
- port: CDP_PORT,
79
+ wsEndpoint: wsEndpoint,
74
80
  launchedAt: Date.now()
75
81
  }));
82
+ logger.dim('Endpoint saved to: ' + CDP_PORT_FILE);
83
+
84
+ logger.success('Browser server started!');
85
+
86
+ // Connect to our own server
87
+ const browser = await chromium.connect({ wsEndpoint });
76
88
 
77
89
  // Create context and page
78
90
  const context = await browser.newContext({
@@ -84,7 +96,10 @@ class BrowserManager {
84
96
  await page.goto(config.YIYAN_URL, { waitUntil: 'domcontentloaded', timeout: 15000 });
85
97
  await page.waitForTimeout(800);
86
98
 
87
- logger.success('Browser launched! Tab ready.');
99
+ logger.success('Tab ready.');
100
+
101
+ // Return without browserServer - let it run independently
102
+ // Do NOT close browserServer on process exit
88
103
  return { browser, context, page, isNew: true };
89
104
  }
90
105
 
package/src/index.js CHANGED
@@ -151,24 +151,25 @@ async function main() {
151
151
  const agent = new YiyanAgent({ saveLog: opts.saveLog });
152
152
 
153
153
  // ── Graceful shutdown handler ──────────────────────────────────────────────
154
- // Only close browser on explicit exit (Ctrl+C, error)
155
- const shutdown = async (code = 0) => {
156
- logger.info('\nShutting down...');
157
- try { await BrowserManager.forceClose(); } catch {}
154
+ // Only delete endpoint file on Ctrl+C (explicit exit)
155
+ const shutdown = async (code = 0, keepBrowser = true) => {
156
+ if (!keepBrowser) {
157
+ try { BrowserManager.forceClose(); } catch {}
158
+ }
158
159
  process.exit(code);
159
160
  };
160
161
 
161
- process.on('SIGINT', () => shutdown(0));
162
- process.on('SIGTERM', () => shutdown(0));
162
+ process.on('SIGINT', () => shutdown(0, false)); // Ctrl+C: close browser
163
+ process.on('SIGTERM', () => shutdown(0, false)); // Kill: close browser
163
164
  process.on('uncaughtException', async err => {
164
165
  logger.error(`Uncaught error: ${err.message}`);
165
166
  if (config.DEBUG) console.error(err.stack);
166
- await shutdown(1);
167
+ await shutdown(1, false); // Error: close browser
167
168
  });
168
169
  process.on('unhandledRejection', async reason => {
169
170
  logger.error(`Unhandled rejection: ${reason}`);
170
171
  if (config.DEBUG) console.error(reason);
171
- await shutdown(1);
172
+ await shutdown(1, false); // Error: close browser
172
173
  });
173
174
 
174
175
  // ── Calibrate mode ─────────────────────────────────────────────────────────