agent-browser 0.0.0 → 0.1.1

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.
Files changed (54) hide show
  1. package/.prettierrc +7 -0
  2. package/LICENSE +201 -0
  3. package/README.md +274 -1
  4. package/bin/agent-browser +2 -0
  5. package/dist/actions.d.ts +7 -0
  6. package/dist/actions.d.ts.map +1 -0
  7. package/dist/actions.js +1138 -0
  8. package/dist/actions.js.map +1 -0
  9. package/dist/browser.d.ts +232 -0
  10. package/dist/browser.d.ts.map +1 -0
  11. package/dist/browser.js +477 -0
  12. package/dist/browser.js.map +1 -0
  13. package/dist/browser.test.d.ts +2 -0
  14. package/dist/browser.test.d.ts.map +1 -0
  15. package/dist/browser.test.js +136 -0
  16. package/dist/browser.test.js.map +1 -0
  17. package/dist/client.d.ts +17 -0
  18. package/dist/client.d.ts.map +1 -0
  19. package/dist/client.js +133 -0
  20. package/dist/client.js.map +1 -0
  21. package/dist/daemon.d.ts +29 -0
  22. package/dist/daemon.d.ts.map +1 -0
  23. package/dist/daemon.js +165 -0
  24. package/dist/daemon.js.map +1 -0
  25. package/dist/index.d.ts +3 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +1158 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/protocol.d.ts +26 -0
  30. package/dist/protocol.d.ts.map +1 -0
  31. package/dist/protocol.js +717 -0
  32. package/dist/protocol.js.map +1 -0
  33. package/dist/protocol.test.d.ts +2 -0
  34. package/dist/protocol.test.d.ts.map +1 -0
  35. package/dist/protocol.test.js +176 -0
  36. package/dist/protocol.test.js.map +1 -0
  37. package/dist/types.d.ts +604 -0
  38. package/dist/types.d.ts.map +1 -0
  39. package/dist/types.js +2 -0
  40. package/dist/types.js.map +1 -0
  41. package/package.json +39 -8
  42. package/scripts/postinstall.js +17 -0
  43. package/src/actions.ts +1658 -0
  44. package/src/browser.test.ts +157 -0
  45. package/src/browser.ts +586 -0
  46. package/src/client.ts +150 -0
  47. package/src/daemon.ts +187 -0
  48. package/src/index.ts +1180 -0
  49. package/src/protocol.test.ts +216 -0
  50. package/src/protocol.ts +848 -0
  51. package/src/types.ts +913 -0
  52. package/tsconfig.json +19 -0
  53. package/vitest.config.ts +9 -0
  54. package/index.js +0 -2
package/dist/client.js ADDED
@@ -0,0 +1,133 @@
1
+ import * as net from 'net';
2
+ import { spawn } from 'child_process';
3
+ import { fileURLToPath } from 'url';
4
+ import * as path from 'path';
5
+ import * as fs from 'fs';
6
+ import { getSocketPath, isDaemonRunning, setSession, getSession } from './daemon.js';
7
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
+ let DEBUG = false;
9
+ export function setDebug(enabled) {
10
+ DEBUG = enabled;
11
+ }
12
+ export { setSession, getSession };
13
+ function debug(...args) {
14
+ if (DEBUG) {
15
+ console.error('[debug]', ...args);
16
+ }
17
+ }
18
+ /**
19
+ * Wait for socket to exist
20
+ */
21
+ async function waitForSocket(maxAttempts = 30) {
22
+ const socketPath = getSocketPath();
23
+ debug('Waiting for socket at', socketPath);
24
+ for (let i = 0; i < maxAttempts; i++) {
25
+ if (fs.existsSync(socketPath)) {
26
+ debug('Socket found after', i * 100, 'ms');
27
+ return true;
28
+ }
29
+ await new Promise((r) => setTimeout(r, 100));
30
+ }
31
+ debug('Socket not found after', maxAttempts * 100, 'ms');
32
+ return false;
33
+ }
34
+ /**
35
+ * Ensure daemon is running, start if not
36
+ */
37
+ export async function ensureDaemon() {
38
+ const session = getSession();
39
+ debug(`Checking if daemon is running for session "${session}"...`);
40
+ if (isDaemonRunning()) {
41
+ debug('Daemon already running');
42
+ return;
43
+ }
44
+ debug('Starting daemon...');
45
+ const daemonPath = path.join(__dirname, 'daemon.js');
46
+ const child = spawn(process.execPath, [daemonPath], {
47
+ detached: true,
48
+ stdio: 'ignore',
49
+ env: { ...process.env, AGENT_BROWSER_DAEMON: '1', AGENT_BROWSER_SESSION: session },
50
+ });
51
+ child.unref();
52
+ // Wait for socket to be created
53
+ const ready = await waitForSocket();
54
+ if (!ready) {
55
+ throw new Error('Failed to start daemon');
56
+ }
57
+ debug(`Daemon started for session "${session}"`);
58
+ }
59
+ /**
60
+ * Send a command to the daemon
61
+ */
62
+ export async function sendCommand(command) {
63
+ const socketPath = getSocketPath();
64
+ debug('Sending command:', JSON.stringify(command));
65
+ return new Promise((resolve, reject) => {
66
+ let resolved = false;
67
+ let buffer = '';
68
+ const startTime = Date.now();
69
+ const socket = net.createConnection(socketPath);
70
+ socket.on('connect', () => {
71
+ debug('Connected to daemon, sending command...');
72
+ socket.write(JSON.stringify(command) + '\n');
73
+ });
74
+ socket.on('data', (data) => {
75
+ buffer += data.toString();
76
+ debug('Received data:', buffer.length, 'bytes');
77
+ // Try to parse complete JSON from buffer
78
+ const newlineIdx = buffer.indexOf('\n');
79
+ if (newlineIdx !== -1) {
80
+ const jsonStr = buffer.substring(0, newlineIdx);
81
+ try {
82
+ const response = JSON.parse(jsonStr);
83
+ debug('Response received in', Date.now() - startTime, 'ms');
84
+ resolved = true;
85
+ socket.end();
86
+ resolve(response);
87
+ }
88
+ catch (e) {
89
+ debug('JSON parse error:', e);
90
+ }
91
+ }
92
+ });
93
+ socket.on('error', (err) => {
94
+ debug('Socket error:', err.message);
95
+ if (!resolved) {
96
+ reject(new Error(`Connection error: ${err.message}`));
97
+ }
98
+ });
99
+ socket.on('close', () => {
100
+ debug('Socket closed, resolved:', resolved, 'buffer:', buffer.length);
101
+ if (!resolved && buffer.trim()) {
102
+ try {
103
+ const response = JSON.parse(buffer.trim());
104
+ resolve(response);
105
+ }
106
+ catch {
107
+ reject(new Error('Invalid response from daemon'));
108
+ }
109
+ }
110
+ else if (!resolved) {
111
+ reject(new Error('Connection closed without response'));
112
+ }
113
+ });
114
+ // Timeout after 15 seconds (allows for 10s Playwright timeout + overhead)
115
+ setTimeout(() => {
116
+ if (!resolved) {
117
+ debug('Command timeout after 15s');
118
+ socket.destroy();
119
+ reject(new Error('Command timeout'));
120
+ }
121
+ }, 15000);
122
+ });
123
+ }
124
+ /**
125
+ * Send a command, ensuring daemon is running first
126
+ */
127
+ export async function send(command) {
128
+ const startTime = Date.now();
129
+ await ensureDaemon();
130
+ debug('ensureDaemon took', Date.now() - startTime, 'ms');
131
+ return sendCommand(command);
132
+ }
133
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Set the current session
3
+ */
4
+ export declare function setSession(session: string): void;
5
+ /**
6
+ * Get the current session
7
+ */
8
+ export declare function getSession(): string;
9
+ /**
10
+ * Get the socket path for the current session
11
+ */
12
+ export declare function getSocketPath(session?: string): string;
13
+ /**
14
+ * Get the PID file path for the current session
15
+ */
16
+ export declare function getPidFile(session?: string): string;
17
+ /**
18
+ * Check if daemon is running for the current session
19
+ */
20
+ export declare function isDaemonRunning(session?: string): boolean;
21
+ /**
22
+ * Clean up socket and PID file for the current session
23
+ */
24
+ export declare function cleanupSocket(session?: string): void;
25
+ /**
26
+ * Start the daemon server
27
+ */
28
+ export declare function startDaemon(): Promise<void>;
29
+ //# sourceMappingURL=daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAWA;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAczD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CASpD;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAoGjD"}
package/dist/daemon.js ADDED
@@ -0,0 +1,165 @@
1
+ import * as net from 'net';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import * as os from 'os';
5
+ import { BrowserManager } from './browser.js';
6
+ import { parseCommand, serializeResponse, errorResponse } from './protocol.js';
7
+ import { executeCommand } from './actions.js';
8
+ // Session support - each session gets its own socket/pid
9
+ let currentSession = process.env.AGENT_BROWSER_SESSION || 'default';
10
+ /**
11
+ * Set the current session
12
+ */
13
+ export function setSession(session) {
14
+ currentSession = session;
15
+ }
16
+ /**
17
+ * Get the current session
18
+ */
19
+ export function getSession() {
20
+ return currentSession;
21
+ }
22
+ /**
23
+ * Get the socket path for the current session
24
+ */
25
+ export function getSocketPath(session) {
26
+ const sess = session ?? currentSession;
27
+ return path.join(os.tmpdir(), `agent-browser-${sess}.sock`);
28
+ }
29
+ /**
30
+ * Get the PID file path for the current session
31
+ */
32
+ export function getPidFile(session) {
33
+ const sess = session ?? currentSession;
34
+ return path.join(os.tmpdir(), `agent-browser-${sess}.pid`);
35
+ }
36
+ /**
37
+ * Check if daemon is running for the current session
38
+ */
39
+ export function isDaemonRunning(session) {
40
+ const pidFile = getPidFile(session);
41
+ if (!fs.existsSync(pidFile))
42
+ return false;
43
+ try {
44
+ const pid = parseInt(fs.readFileSync(pidFile, 'utf8').trim(), 10);
45
+ // Check if process exists
46
+ process.kill(pid, 0);
47
+ return true;
48
+ }
49
+ catch {
50
+ // Process doesn't exist, clean up stale files
51
+ cleanupSocket(session);
52
+ return false;
53
+ }
54
+ }
55
+ /**
56
+ * Clean up socket and PID file for the current session
57
+ */
58
+ export function cleanupSocket(session) {
59
+ const socketPath = getSocketPath(session);
60
+ const pidFile = getPidFile(session);
61
+ try {
62
+ if (fs.existsSync(socketPath))
63
+ fs.unlinkSync(socketPath);
64
+ if (fs.existsSync(pidFile))
65
+ fs.unlinkSync(pidFile);
66
+ }
67
+ catch {
68
+ // Ignore cleanup errors
69
+ }
70
+ }
71
+ /**
72
+ * Start the daemon server
73
+ */
74
+ export async function startDaemon() {
75
+ // Clean up any stale socket
76
+ cleanupSocket();
77
+ const browser = new BrowserManager();
78
+ let shuttingDown = false;
79
+ const server = net.createServer((socket) => {
80
+ let buffer = '';
81
+ socket.on('data', async (data) => {
82
+ buffer += data.toString();
83
+ // Process complete lines
84
+ while (buffer.includes('\n')) {
85
+ const newlineIdx = buffer.indexOf('\n');
86
+ const line = buffer.substring(0, newlineIdx);
87
+ buffer = buffer.substring(newlineIdx + 1);
88
+ if (!line.trim())
89
+ continue;
90
+ try {
91
+ const parseResult = parseCommand(line);
92
+ if (!parseResult.success) {
93
+ const resp = errorResponse(parseResult.id ?? 'unknown', parseResult.error);
94
+ socket.write(serializeResponse(resp) + '\n');
95
+ continue;
96
+ }
97
+ // Auto-launch browser if not already launched and this isn't a launch command
98
+ if (!browser.isLaunched() &&
99
+ parseResult.command.action !== 'launch' &&
100
+ parseResult.command.action !== 'close') {
101
+ await browser.launch({ id: 'auto', action: 'launch', headless: true });
102
+ }
103
+ // Handle close command specially
104
+ if (parseResult.command.action === 'close') {
105
+ const response = await executeCommand(parseResult.command, browser);
106
+ socket.write(serializeResponse(response) + '\n');
107
+ if (!shuttingDown) {
108
+ shuttingDown = true;
109
+ setTimeout(() => {
110
+ server.close();
111
+ cleanupSocket();
112
+ process.exit(0);
113
+ }, 100);
114
+ }
115
+ return;
116
+ }
117
+ const response = await executeCommand(parseResult.command, browser);
118
+ socket.write(serializeResponse(response) + '\n');
119
+ }
120
+ catch (err) {
121
+ const message = err instanceof Error ? err.message : String(err);
122
+ socket.write(serializeResponse(errorResponse('error', message)) + '\n');
123
+ }
124
+ }
125
+ });
126
+ socket.on('error', () => {
127
+ // Client disconnected, ignore
128
+ });
129
+ });
130
+ const socketPath = getSocketPath();
131
+ const pidFile = getPidFile();
132
+ // Write PID file before listening
133
+ fs.writeFileSync(pidFile, process.pid.toString());
134
+ server.listen(socketPath, () => {
135
+ // Daemon is ready
136
+ });
137
+ server.on('error', (err) => {
138
+ console.error('Server error:', err);
139
+ cleanupSocket();
140
+ process.exit(1);
141
+ });
142
+ // Handle shutdown signals
143
+ const shutdown = async () => {
144
+ if (shuttingDown)
145
+ return;
146
+ shuttingDown = true;
147
+ await browser.close();
148
+ server.close();
149
+ cleanupSocket();
150
+ process.exit(0);
151
+ };
152
+ process.on('SIGINT', shutdown);
153
+ process.on('SIGTERM', shutdown);
154
+ // Keep process alive
155
+ process.stdin.resume();
156
+ }
157
+ // Run daemon if this is the entry point
158
+ if (process.argv[1]?.endsWith('daemon.js') || process.env.AGENT_BROWSER_DAEMON === '1') {
159
+ startDaemon().catch((err) => {
160
+ console.error('Daemon error:', err);
161
+ cleanupSocket();
162
+ process.exit(1);
163
+ });
164
+ }
165
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}