yiyan-browser-agent 1.0.22 → 1.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yiyan-browser-agent",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
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": {
@@ -10,35 +10,47 @@ const config = require('./config');
10
10
 
11
11
  const CDP_PORT_FILE = path.join(os.homedir(), '.yiyan-agent', 'cdp-port.json');
12
12
  const CDP_PORT = 9222;
13
+ const SESSION_DIR = path.join(os.homedir(), '.yiyan-agent', 'session');
13
14
 
14
15
  class BrowserManager {
15
16
  /**
16
17
  * Get browser - connect existing or launch new
17
18
  */
18
19
  static async getInstance() {
20
+ // Ensure directories exist
21
+ fs.mkdirSync(SESSION_DIR, { recursive: true });
22
+
19
23
  // Try connect existing browser
20
24
  try {
21
25
  if (fs.existsSync(CDP_PORT_FILE)) {
22
- const portInfo = JSON.parse(fs.readFileSync(CDP_PORT_FILE, 'utf8'));
23
- const browserURL = `http://localhost:${portInfo.port || CDP_PORT}`;
26
+ const endpointInfo = JSON.parse(fs.readFileSync(CDP_PORT_FILE, 'utf8'));
27
+ const wsEndpoint = endpointInfo.wsEndpoint;
24
28
 
25
- logger.info('Connecting to existing browser...');
26
- const browser = await chromium.connectOverCDP(browserURL, { timeout: 5000 });
29
+ if (!wsEndpoint) {
30
+ throw new Error('No wsEndpoint in file');
31
+ }
27
32
 
28
- // Create NEW page (tab) for this task
29
- const page = await browser.newPage();
33
+ logger.info('Connecting to existing browser...');
34
+ const browser = await chromium.connect({ wsEndpoint, timeout: 5000 });
35
+
36
+ // Create NEW context and page (tab) for this task
37
+ const context = await browser.newContext({
38
+ viewport: { width: 1280, height: 900 },
39
+ userAgent: 'Mozilla/5.0 AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36',
40
+ });
41
+ const page = await context.newPage();
30
42
  await page.goto(config.YIYAN_URL, { waitUntil: 'domcontentloaded', timeout: 15000 });
31
43
  await page.waitForTimeout(500);
32
44
 
33
- logger.success('Connected! Using new tab.');
34
- return { browser, page, isNew: false };
45
+ logger.success('Connected! New tab opened.');
46
+ return { browser, context, page, isNew: false };
35
47
  }
36
48
  } catch (err) {
37
49
  logger.warn('Connection failed, launching new browser...');
38
50
  try { fs.unlinkSync(CDP_PORT_FILE); } catch {}
39
51
  }
40
52
 
41
- // Launch new browser with CDP
53
+ // Launch new browser with CDP port
42
54
  return await this._launchNew();
43
55
  }
44
56
 
@@ -46,53 +58,47 @@ class BrowserManager {
46
58
  * Launch new browser with CDP port
47
59
  */
48
60
  static async _launchNew() {
49
- logger.info('Launching new browser...');
50
-
51
- // Ensure session directory
52
- const sessionDir = path.join(os.homedir(), '.yiyan-agent', 'session');
53
- fs.mkdirSync(sessionDir, { recursive: true });
61
+ logger.info('Launching new browser server...');
54
62
 
55
- // Launch with persistent context + CDP port
56
- const context = await chromium.launchPersistentContext(sessionDir, {
63
+ // Use launchServer to create independent browser process
64
+ // Browser will NOT close when Node.js process exits
65
+ const browserServer = await chromium.launchServer({
57
66
  headless: false,
58
- viewport: { width: 1280, height: 900 },
59
67
  args: [
60
- `--remote-debugging-port=${CDP_PORT}`,
61
68
  '--disable-blink-features=AutomationControlled',
62
69
  '--no-first-run',
63
70
  '--no-sandbox',
64
71
  ],
65
- userAgent: 'Mozilla/5.0 AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36',
66
72
  });
67
73
 
68
- // Get the browser from context
69
- const browser = context.browser();
74
+ // Get the WebSocket endpoint
75
+ const wsEndpoint = browserServer.wsEndpoint();
76
+ const port = wsEndpoint.match(/:(\d+)/)?.[1] || CDP_PORT;
70
77
 
71
- // Save CDP port
78
+ // Save endpoint info
72
79
  fs.writeFileSync(CDP_PORT_FILE, JSON.stringify({
73
- port: CDP_PORT,
74
- pid: process.pid,
80
+ wsEndpoint: wsEndpoint,
81
+ port: port,
75
82
  launchedAt: Date.now()
76
83
  }));
77
84
 
78
- // Use existing page or create new
79
- const pages = context.pages();
80
- const page = pages.length > 0 ? pages[0] : await context.newPage();
85
+ logger.success('Browser server started!');
86
+
87
+ // Connect to our own server
88
+ const browser = await chromium.connect({ wsEndpoint });
89
+
90
+ // Create context and page
91
+ const context = await browser.newContext({
92
+ viewport: { width: 1280, height: 900 },
93
+ userAgent: 'Mozilla/5.0 AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36',
94
+ });
95
+ const page = await context.newPage();
81
96
 
82
97
  await page.goto(config.YIYAN_URL, { waitUntil: 'domcontentloaded', timeout: 15000 });
83
98
  await page.waitForTimeout(800);
84
99
 
85
- logger.success('Browser launched! Tab ready.');
86
- return { browser, context, page, isNew: true };
87
- }
88
-
89
- /**
90
- * Close current page (tab) but keep browser running
91
- */
92
- static async closePage(page) {
93
- try {
94
- await page.close();
95
- } catch {}
100
+ logger.success('Tab ready.');
101
+ return { browser, context, page, isNew: true, browserServer };
96
102
  }
97
103
 
98
104
  /**
@@ -100,7 +106,7 @@ class BrowserManager {
100
106
  */
101
107
  static async forceClose() {
102
108
  try { fs.unlinkSync(CDP_PORT_FILE); } catch {}
103
- // Browser will close when user does Ctrl+C or manually
109
+ // Browser continues running independently
104
110
  }
105
111
  }
106
112