@elizaos/plugin-browser 2.0.0-alpha.1 → 2.0.0-alpha.4

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.
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Browser CLI module
3
+ *
4
+ * Provides CLI commands for the browser automation plugin.
5
+ * Self-registers with the plugin-cli registry at module load.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Browser CLI module
3
+ *
4
+ * Provides CLI commands for the browser automation plugin.
5
+ * Self-registers with the plugin-cli registry at module load.
6
+ */
7
+ import { defineCliCommand, registerCliCommand } from "@elizaos/plugin-cli";
8
+ import { registerBrowserCli } from "./register.js";
9
+ // Self-register at module load
10
+ registerCliCommand(defineCliCommand("browser", "Browser automation commands", (ctx) => registerBrowserCli(ctx), {
11
+ priority: 50,
12
+ }));
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,+BAA+B;AAC/B,kBAAkB,CAChB,gBAAgB,CAAC,SAAS,EAAE,6BAA6B,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE;IAC3F,QAAQ,EAAE,EAAE;CACb,CAAC,CACH,CAAC","sourcesContent":["/**\n * Browser CLI module\n *\n * Provides CLI commands for the browser automation plugin.\n * Self-registers with the plugin-cli registry at module load.\n */\n\nimport { defineCliCommand, registerCliCommand } from \"@elizaos/plugin-cli\";\nimport { registerBrowserCli } from \"./register.js\";\n\n// Self-register at module load\nregisterCliCommand(\n defineCliCommand(\"browser\", \"Browser automation commands\", (ctx) => registerBrowserCli(ctx), {\n priority: 50,\n })\n);\n"]}
@@ -0,0 +1,20 @@
1
+ import type { CliContext } from "@elizaos/plugin-cli";
2
+ /**
3
+ * Register Browser CLI commands
4
+ *
5
+ * Commands:
6
+ * - browser status: Show browser service status
7
+ * - browser start: Start a browser session
8
+ * - browser stop: Stop browser service
9
+ * - browser navigate: Navigate to a URL
10
+ * - browser click: Click an element
11
+ * - browser type: Type text into a field
12
+ * - browser select: Select an option from dropdown
13
+ * - browser extract: Extract information from the page
14
+ * - browser screenshot: Take a screenshot
15
+ * - browser back/forward/refresh: Navigation controls
16
+ *
17
+ * @param ctx - CLI context with program and optional runtime
18
+ */
19
+ export declare function registerBrowserCli(ctx: CliContext): void;
20
+ //# sourceMappingURL=register.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/cli/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAyCtD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAyYxD"}
@@ -0,0 +1,399 @@
1
+ import { BrowserService } from "../services/browser-service.js";
2
+ /**
3
+ * Get the Browser service from runtime
4
+ */
5
+ function getBrowserService(ctx) {
6
+ const runtime = ctx.getRuntime?.();
7
+ if (!runtime) {
8
+ return null;
9
+ }
10
+ return runtime.getService(BrowserService.serviceType);
11
+ }
12
+ /**
13
+ * Handle errors in browser commands
14
+ */
15
+ function handleError(error) {
16
+ const message = error instanceof Error ? error.message : String(error);
17
+ console.error(`Error: ${message}`);
18
+ process.exit(1);
19
+ }
20
+ /**
21
+ * Ensure service is available
22
+ */
23
+ function requireService(ctx) {
24
+ const service = getBrowserService(ctx);
25
+ if (!service) {
26
+ handleError("Browser service not available. Ensure the agent runtime is initialized.");
27
+ }
28
+ return service;
29
+ }
30
+ /**
31
+ * Format navigation result for display
32
+ */
33
+ function formatNavigationResult(result) {
34
+ return [`Success: ${result.success}`, `URL: ${result.url}`, `Title: ${result.title}`].join("\n");
35
+ }
36
+ /**
37
+ * Register Browser CLI commands
38
+ *
39
+ * Commands:
40
+ * - browser status: Show browser service status
41
+ * - browser start: Start a browser session
42
+ * - browser stop: Stop browser service
43
+ * - browser navigate: Navigate to a URL
44
+ * - browser click: Click an element
45
+ * - browser type: Type text into a field
46
+ * - browser select: Select an option from dropdown
47
+ * - browser extract: Extract information from the page
48
+ * - browser screenshot: Take a screenshot
49
+ * - browser back/forward/refresh: Navigation controls
50
+ *
51
+ * @param ctx - CLI context with program and optional runtime
52
+ */
53
+ export function registerBrowserCli(ctx) {
54
+ const browser = ctx.program
55
+ .command("browser")
56
+ .description("Browser automation commands")
57
+ .option("--json", "Output as JSON", false);
58
+ // Status command
59
+ browser
60
+ .command("status")
61
+ .description("Show browser service status")
62
+ .action(async (_opts, cmd) => {
63
+ const parent = cmd.parent?.opts();
64
+ const service = getBrowserService(ctx);
65
+ const status = {
66
+ serviceAvailable: service !== null,
67
+ serverConnected: service?.getClient?.()?.isConnected?.() ?? false,
68
+ };
69
+ let currentSession;
70
+ if (service) {
71
+ currentSession = await service.getCurrentSession();
72
+ }
73
+ const output = {
74
+ ...status,
75
+ hasActiveSession: !!currentSession,
76
+ sessionId: currentSession?.id ?? null,
77
+ };
78
+ if (parent?.json) {
79
+ console.log(JSON.stringify(output, null, 2));
80
+ }
81
+ else {
82
+ console.log("Browser Service Status:");
83
+ console.log(` Service available: ${output.serviceAvailable}`);
84
+ console.log(` Server connected: ${output.serverConnected}`);
85
+ console.log(` Active session: ${output.hasActiveSession ? output.sessionId : "none"}`);
86
+ }
87
+ });
88
+ // Start command
89
+ browser
90
+ .command("start")
91
+ .description("Start or ensure browser session is active")
92
+ .action(async (_opts, cmd) => {
93
+ const parent = cmd.parent?.opts();
94
+ const service = requireService(ctx);
95
+ const session = await service.getOrCreateSession();
96
+ if (parent?.json) {
97
+ console.log(JSON.stringify({ sessionId: session.id, createdAt: session.createdAt }, null, 2));
98
+ }
99
+ else {
100
+ console.log(`Browser session active: ${session.id}`);
101
+ }
102
+ });
103
+ // Stop command
104
+ browser
105
+ .command("stop")
106
+ .description("Stop browser service")
107
+ .action(async (_opts, cmd) => {
108
+ const parent = cmd.parent?.opts();
109
+ const service = requireService(ctx);
110
+ await service.stop();
111
+ if (parent?.json) {
112
+ console.log(JSON.stringify({ stopped: true }, null, 2));
113
+ }
114
+ else {
115
+ console.log("Browser service stopped");
116
+ }
117
+ });
118
+ // Navigate command
119
+ browser
120
+ .command("navigate")
121
+ .description("Navigate to a URL")
122
+ .argument("<url>", "URL to navigate to")
123
+ .action(async (url, _opts, cmd) => {
124
+ const parent = cmd.parent?.opts();
125
+ const service = requireService(ctx);
126
+ const client = service.getClient();
127
+ const session = await service.getOrCreateSession();
128
+ const result = await client.navigate(session.id, url);
129
+ if (parent?.json) {
130
+ console.log(JSON.stringify(result, null, 2));
131
+ }
132
+ else {
133
+ console.log(formatNavigationResult(result));
134
+ }
135
+ });
136
+ // Go back command
137
+ browser
138
+ .command("back")
139
+ .description("Navigate back in browser history")
140
+ .action(async (_opts, cmd) => {
141
+ const parent = cmd.parent?.opts();
142
+ const service = requireService(ctx);
143
+ const client = service.getClient();
144
+ const session = await service.getCurrentSession();
145
+ if (!session) {
146
+ handleError("No active browser session");
147
+ }
148
+ const result = await client.goBack(session.id);
149
+ if (parent?.json) {
150
+ console.log(JSON.stringify(result, null, 2));
151
+ }
152
+ else {
153
+ console.log(formatNavigationResult(result));
154
+ }
155
+ });
156
+ // Go forward command
157
+ browser
158
+ .command("forward")
159
+ .description("Navigate forward in browser history")
160
+ .action(async (_opts, cmd) => {
161
+ const parent = cmd.parent?.opts();
162
+ const service = requireService(ctx);
163
+ const client = service.getClient();
164
+ const session = await service.getCurrentSession();
165
+ if (!session) {
166
+ handleError("No active browser session");
167
+ }
168
+ const result = await client.goForward(session.id);
169
+ if (parent?.json) {
170
+ console.log(JSON.stringify(result, null, 2));
171
+ }
172
+ else {
173
+ console.log(formatNavigationResult(result));
174
+ }
175
+ });
176
+ // Refresh command
177
+ browser
178
+ .command("refresh")
179
+ .description("Refresh the current page")
180
+ .action(async (_opts, cmd) => {
181
+ const parent = cmd.parent?.opts();
182
+ const service = requireService(ctx);
183
+ const client = service.getClient();
184
+ const session = await service.getCurrentSession();
185
+ if (!session) {
186
+ handleError("No active browser session");
187
+ }
188
+ const result = await client.refresh(session.id);
189
+ if (parent?.json) {
190
+ console.log(JSON.stringify(result, null, 2));
191
+ }
192
+ else {
193
+ console.log(formatNavigationResult(result));
194
+ }
195
+ });
196
+ // Click command
197
+ browser
198
+ .command("click")
199
+ .description("Click an element on the page")
200
+ .argument("<description>", "Description of the element to click (natural language)")
201
+ .action(async (description, _opts, cmd) => {
202
+ const parent = cmd.parent?.opts();
203
+ const service = requireService(ctx);
204
+ const client = service.getClient();
205
+ const session = await service.getCurrentSession();
206
+ if (!session) {
207
+ handleError("No active browser session");
208
+ }
209
+ const result = await client.click(session.id, description);
210
+ if (parent?.json) {
211
+ console.log(JSON.stringify(result.data ?? { success: true }, null, 2));
212
+ }
213
+ else {
214
+ console.log(`Clicked: ${description}`);
215
+ if (result.data) {
216
+ console.log(JSON.stringify(result.data, null, 2));
217
+ }
218
+ }
219
+ });
220
+ // Type command
221
+ browser
222
+ .command("type")
223
+ .description("Type text into a field")
224
+ .argument("<text>", "Text to type")
225
+ .requiredOption("--field <description>", "Description of the field (natural language)")
226
+ .action(async (text, opts, cmd) => {
227
+ const parent = cmd.parent?.opts();
228
+ const service = requireService(ctx);
229
+ const client = service.getClient();
230
+ const session = await service.getCurrentSession();
231
+ if (!session) {
232
+ handleError("No active browser session");
233
+ }
234
+ const result = await client.type(session.id, text, opts.field);
235
+ if (parent?.json) {
236
+ console.log(JSON.stringify(result.data ?? { success: true }, null, 2));
237
+ }
238
+ else {
239
+ console.log(`Typed "${text}" into: ${opts.field}`);
240
+ if (result.data) {
241
+ console.log(JSON.stringify(result.data, null, 2));
242
+ }
243
+ }
244
+ });
245
+ // Select command
246
+ browser
247
+ .command("select")
248
+ .description("Select an option from a dropdown")
249
+ .argument("<option>", "Option to select")
250
+ .requiredOption("--dropdown <description>", "Description of the dropdown (natural language)")
251
+ .action(async (option, opts, cmd) => {
252
+ const parent = cmd.parent?.opts();
253
+ const service = requireService(ctx);
254
+ const client = service.getClient();
255
+ const session = await service.getCurrentSession();
256
+ if (!session) {
257
+ handleError("No active browser session");
258
+ }
259
+ const result = await client.select(session.id, option, opts.dropdown);
260
+ if (parent?.json) {
261
+ console.log(JSON.stringify(result.data ?? { success: true }, null, 2));
262
+ }
263
+ else {
264
+ console.log(`Selected "${option}" from: ${opts.dropdown}`);
265
+ if (result.data) {
266
+ console.log(JSON.stringify(result.data, null, 2));
267
+ }
268
+ }
269
+ });
270
+ // Extract command
271
+ browser
272
+ .command("extract")
273
+ .description("Extract information from the page")
274
+ .argument("<instruction>", "What to extract (natural language)")
275
+ .action(async (instruction, _opts, cmd) => {
276
+ const parent = cmd.parent?.opts();
277
+ const service = requireService(ctx);
278
+ const client = service.getClient();
279
+ const session = await service.getCurrentSession();
280
+ if (!session) {
281
+ handleError("No active browser session");
282
+ }
283
+ const result = await client.extract(session.id, instruction);
284
+ if (parent?.json) {
285
+ console.log(JSON.stringify(result.data ?? {}, null, 2));
286
+ }
287
+ else {
288
+ console.log(`Extracted: ${instruction}`);
289
+ console.log(JSON.stringify(result.data ?? {}, null, 2));
290
+ }
291
+ });
292
+ // Screenshot command
293
+ browser
294
+ .command("screenshot")
295
+ .description("Take a screenshot of the current page")
296
+ .option("--output <path>", "Output file path")
297
+ .action(async (opts, cmd) => {
298
+ const parent = cmd.parent?.opts();
299
+ const service = requireService(ctx);
300
+ const client = service.getClient();
301
+ const session = await service.getCurrentSession();
302
+ if (!session) {
303
+ handleError("No active browser session");
304
+ }
305
+ const result = await client.screenshot(session.id);
306
+ const data = result.data;
307
+ if (parent?.json) {
308
+ console.log(JSON.stringify({
309
+ success: !!data?.screenshot,
310
+ hasScreenshot: !!data?.screenshot,
311
+ outputPath: opts.output ?? null,
312
+ }, null, 2));
313
+ }
314
+ else {
315
+ if (data?.screenshot) {
316
+ if (opts.output) {
317
+ const fs = await import("node:fs/promises");
318
+ const buffer = Buffer.from(data.screenshot, "base64");
319
+ await fs.writeFile(opts.output, buffer);
320
+ console.log(`Screenshot saved to: ${opts.output}`);
321
+ }
322
+ else {
323
+ console.log("Screenshot captured (use --output to save to file)");
324
+ console.log(`Base64 length: ${data.screenshot.length}`);
325
+ }
326
+ }
327
+ else {
328
+ console.log("Failed to capture screenshot");
329
+ }
330
+ }
331
+ });
332
+ // State command
333
+ browser
334
+ .command("state")
335
+ .description("Get current browser state")
336
+ .action(async (_opts, cmd) => {
337
+ const parent = cmd.parent?.opts();
338
+ const service = requireService(ctx);
339
+ const client = service.getClient();
340
+ const session = await service.getCurrentSession();
341
+ if (!session) {
342
+ handleError("No active browser session");
343
+ }
344
+ const state = await client.getState(session.id);
345
+ if (parent?.json) {
346
+ console.log(JSON.stringify(state, null, 2));
347
+ }
348
+ else {
349
+ console.log("Browser State:");
350
+ console.log(` URL: ${state.url}`);
351
+ console.log(` Title: ${state.title}`);
352
+ console.log(` Session ID: ${state.sessionId}`);
353
+ }
354
+ });
355
+ // Solve captcha command
356
+ browser
357
+ .command("solve-captcha")
358
+ .description("Attempt to solve a captcha on the page")
359
+ .action(async (_opts, cmd) => {
360
+ const parent = cmd.parent?.opts();
361
+ const service = requireService(ctx);
362
+ const client = service.getClient();
363
+ const session = await service.getCurrentSession();
364
+ if (!session) {
365
+ handleError("No active browser session");
366
+ }
367
+ const result = await client.solveCaptcha(session.id);
368
+ if (parent?.json) {
369
+ console.log(JSON.stringify(result.data ?? { attempted: true }, null, 2));
370
+ }
371
+ else {
372
+ console.log("Captcha solve attempted");
373
+ if (result.data) {
374
+ console.log(JSON.stringify(result.data, null, 2));
375
+ }
376
+ }
377
+ });
378
+ // Health command
379
+ browser
380
+ .command("health")
381
+ .description("Check browser server health")
382
+ .action(async (_opts, cmd) => {
383
+ const parent = cmd.parent?.opts();
384
+ const service = getBrowserService(ctx);
385
+ let healthy = false;
386
+ if (service) {
387
+ const client = service.getClient();
388
+ healthy = await client.health();
389
+ }
390
+ if (parent?.json) {
391
+ console.log(JSON.stringify({ healthy, serviceAvailable: !!service }, null, 2));
392
+ }
393
+ else {
394
+ console.log(`Browser server health: ${healthy ? "OK" : "UNHEALTHY"}`);
395
+ console.log(`Service available: ${!!service}`);
396
+ }
397
+ });
398
+ }
399
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/cli/register.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CliContext } from \"@elizaos/plugin-cli\";\nimport { BrowserService, type Session } from \"../services/browser-service.js\";\n\n/**\n * Get the Browser service from runtime\n */\nfunction getBrowserService(ctx: CliContext): BrowserService | null {\n const runtime = ctx.getRuntime?.();\n if (!runtime) {\n return null;\n }\n return runtime.getService<BrowserService>(BrowserService.serviceType);\n}\n\n/**\n * Handle errors in browser commands\n */\nfunction handleError(error: Error | string): never {\n const message = error instanceof Error ? error.message : String(error);\n console.error(`Error: ${message}`);\n process.exit(1);\n}\n\n/**\n * Ensure service is available\n */\nfunction requireService(ctx: CliContext): BrowserService {\n const service = getBrowserService(ctx);\n if (!service) {\n handleError(\"Browser service not available. Ensure the agent runtime is initialized.\");\n }\n return service;\n}\n\n/**\n * Format navigation result for display\n */\nfunction formatNavigationResult(result: { success: boolean; url: string; title: string }): string {\n return [`Success: ${result.success}`, `URL: ${result.url}`, `Title: ${result.title}`].join(\"\\n\");\n}\n\n/**\n * Register Browser CLI commands\n *\n * Commands:\n * - browser status: Show browser service status\n * - browser start: Start a browser session\n * - browser stop: Stop browser service\n * - browser navigate: Navigate to a URL\n * - browser click: Click an element\n * - browser type: Type text into a field\n * - browser select: Select an option from dropdown\n * - browser extract: Extract information from the page\n * - browser screenshot: Take a screenshot\n * - browser back/forward/refresh: Navigation controls\n *\n * @param ctx - CLI context with program and optional runtime\n */\nexport function registerBrowserCli(ctx: CliContext): void {\n const browser = ctx.program\n .command(\"browser\")\n .description(\"Browser automation commands\")\n .option(\"--json\", \"Output as JSON\", false);\n\n // Status command\n browser\n .command(\"status\")\n .description(\"Show browser service status\")\n .action(async (_opts, cmd) => {\n const parent = cmd.parent?.opts() as { json?: boolean } | undefined;\n const service = getBrowserService(ctx);\n\n const status = {\n serviceAvailable: service !== null,\n serverConnected: service?.getClient?.()?.isConnected?.() ?? false,\n };\n\n let currentSession: Session | undefined;\n if (service) {\n currentSession = await service.getCurrentSession();\n }\n\n const output = {\n ...status,\n hasActiveSession: !!currentSession,\n sessionId: currentSession?.id ?? null,\n };\n\n if (parent?.json) {\n console.log(JSON.stringify(output, null, 2));\n } else {\n console.log(\"Browser Service Status:\");\n console.log(` Service available: ${output.serviceAvailable}`);\n console.log(` Server connected: ${output.serverConnected}`);\n console.log(` Active session: ${output.hasActiveSession ? output.sessionId : \"none\"}`);\n }\n });\n\n // Start command\n browser\n .command(\"start\")\n .description(\"Start or ensure browser session is active\")\n .action(async (_opts, cmd) => {\n const parent = cmd.parent?.opts() as { json?: boolean } | undefined;\n const service = requireService(ctx);\n\n const session = await service.getOrCreateSession();\n\n if (parent?.json) {\n console.log(\n JSON.stringify({ sessionId: session.id, createdAt: session.createdAt }, null, 2)\n );\n } else {\n console.log(`Browser session active: ${session.id}`);\n }\n });\n\n // Stop command\n browser\n .command(\"stop\")\n .description(\"Stop browser service\")\n .action(async (_opts, cmd) => {\n const parent = cmd.parent?.opts() as { json?: boolean } | undefined;\n const service = requireService(ctx);\n\n await service.stop();\n\n if (parent?.json) {\n console.log(JSON.stringify({ stopped: true }, null, 2));\n } else {\n console.log(\"Browser service stopped\");\n }\n });\n\n // Navigate command\n browser\n .command(\"navigate\")\n .description(\"Navigate to a URL\")\n .argument(\"<url>\", \"URL to navigate to\")\n .action(async (url: string, _opts, cmd) => {\n const parent = cmd.parent?.opts() as { json?: boolean } | undefined;\n const service = requireService(ctx);\n const client = service.getClient();\n\n const session = await service.getOrCreateSession();\n const result = await client.navigate(session.id, url);\n\n if (parent?.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(formatNavigationResult(result));\n }\n });\n\n // Go back command\n browser\n .command(\"back\")\n .description(\"Navigate back in browser history\")\n .action(async (_opts, cmd) => {\n const parent = cmd.parent?.opts() as { json?: boolean } | undefined;\n const service = requireService(ctx);\n const client = service.getClient();\n\n const session = await service.getCurrentSession();\n if (!session) {\n handleError(\"No active browser session\");\n }\n\n const result = await client.goBack(session.id);\n\n if (parent?.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(formatNavigationResult(result));\n }\n });\n\n // Go forward command\n browser\n .command(\"forward\")\n .description(\"Navigate forward in browser history\")\n .action(async (_opts, cmd) => {\n const parent = cmd.parent?.opts() as { json?: boolean } | undefined;\n const service = requireService(ctx);\n const client = service.getClient();\n\n const session = await service.getCurrentSession();\n if (!session) {\n handleError(\"No active browser session\");\n }\n\n const result = await client.goForward(session.id);\n\n if (parent?.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(formatNavigationResult(result));\n }\n });\n\n // Refresh command\n browser\n .command(\"refresh\")\n .description(\"Refresh the current page\")\n .action(async (_opts, cmd) => {\n const parent = cmd.parent?.opts() as { json?: boolean } | undefined;\n const service = requireService(ctx);\n const client = service.getClient();\n\n const session = await service.getCurrentSession();\n if (!session) {\n handleError(\"No active browser session\");\n }\n\n const result = await client.refresh(session.id);\n\n if (parent?.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(formatNavigationResult(result));\n }\n });\n\n // Click command\n browser\n .command(\"click\")\n .description(\"Click an element on the page\")\n .argument(\"<description>\", \"Description of the element to click (natural language)\")\n .action(async (description: string, _opts, cmd) => {\n const parent = cmd.parent?.opts() as { json?: boolean } | undefined;\n const service = requireService(ctx);\n const client = service.getClient();\n\n const session = await service.getCurrentSession();\n if (!session) {\n handleError(\"No active browser session\");\n }\n\n const result = await client.click(session.id, description);\n\n if (parent?.json) {\n console.log(JSON.stringify(result.data ?? { success: true }, null, 2));\n } else {\n console.log(`Clicked: ${description}`);\n if (result.data) {\n console.log(JSON.stringify(result.data, null, 2));\n }\n }\n });\n\n // Type command\n browser\n .command(\"type\")\n .description(\"Type text into a field\")\n .argument(\"<text>\", \"Text to type\")\n .requiredOption(\"--field <description>\", \"Description of the field (natural language)\")\n .action(async (text: string, opts: { field: string }, cmd) => {\n const parent = cmd.parent?.opts() as { json?: boolean } | undefined;\n const service = requireService(ctx);\n const client = service.getClient();\n\n const session = await service.getCurrentSession();\n if (!session) {\n handleError(\"No active browser session\");\n }\n\n const result = await client.type(session.id, text, opts.field);\n\n if (parent?.json) {\n console.log(JSON.stringify(result.data ?? { success: true }, null, 2));\n } else {\n console.log(`Typed \"${text}\" into: ${opts.field}`);\n if (result.data) {\n console.log(JSON.stringify(result.data, null, 2));\n }\n }\n });\n\n // Select command\n browser\n .command(\"select\")\n .description(\"Select an option from a dropdown\")\n .argument(\"<option>\", \"Option to select\")\n .requiredOption(\"--dropdown <description>\", \"Description of the dropdown (natural language)\")\n .action(async (option: string, opts: { dropdown: string }, cmd) => {\n const parent = cmd.parent?.opts() as { json?: boolean } | undefined;\n const service = requireService(ctx);\n const client = service.getClient();\n\n const session = await service.getCurrentSession();\n if (!session) {\n handleError(\"No active browser session\");\n }\n\n const result = await client.select(session.id, option, opts.dropdown);\n\n if (parent?.json) {\n console.log(JSON.stringify(result.data ?? { success: true }, null, 2));\n } else {\n console.log(`Selected \"${option}\" from: ${opts.dropdown}`);\n if (result.data) {\n console.log(JSON.stringify(result.data, null, 2));\n }\n }\n });\n\n // Extract command\n browser\n .command(\"extract\")\n .description(\"Extract information from the page\")\n .argument(\"<instruction>\", \"What to extract (natural language)\")\n .action(async (instruction: string, _opts, cmd) => {\n const parent = cmd.parent?.opts() as { json?: boolean } | undefined;\n const service = requireService(ctx);\n const client = service.getClient();\n\n const session = await service.getCurrentSession();\n if (!session) {\n handleError(\"No active browser session\");\n }\n\n const result = await client.extract(session.id, instruction);\n\n if (parent?.json) {\n console.log(JSON.stringify(result.data ?? {}, null, 2));\n } else {\n console.log(`Extracted: ${instruction}`);\n console.log(JSON.stringify(result.data ?? {}, null, 2));\n }\n });\n\n // Screenshot command\n browser\n .command(\"screenshot\")\n .description(\"Take a screenshot of the current page\")\n .option(\"--output <path>\", \"Output file path\")\n .action(async (opts: { output?: string }, cmd) => {\n const parent = cmd.parent?.opts() as { json?: boolean } | undefined;\n const service = requireService(ctx);\n const client = service.getClient();\n\n const session = await service.getCurrentSession();\n if (!session) {\n handleError(\"No active browser session\");\n }\n\n const result = await client.screenshot(session.id);\n const data = result.data as { screenshot?: string } | undefined;\n\n if (parent?.json) {\n console.log(\n JSON.stringify(\n {\n success: !!data?.screenshot,\n hasScreenshot: !!data?.screenshot,\n outputPath: opts.output ?? null,\n },\n null,\n 2\n )\n );\n } else {\n if (data?.screenshot) {\n if (opts.output) {\n const fs = await import(\"node:fs/promises\");\n const buffer = Buffer.from(data.screenshot, \"base64\");\n await fs.writeFile(opts.output, buffer);\n console.log(`Screenshot saved to: ${opts.output}`);\n } else {\n console.log(\"Screenshot captured (use --output to save to file)\");\n console.log(`Base64 length: ${data.screenshot.length}`);\n }\n } else {\n console.log(\"Failed to capture screenshot\");\n }\n }\n });\n\n // State command\n browser\n .command(\"state\")\n .description(\"Get current browser state\")\n .action(async (_opts, cmd) => {\n const parent = cmd.parent?.opts() as { json?: boolean } | undefined;\n const service = requireService(ctx);\n const client = service.getClient();\n\n const session = await service.getCurrentSession();\n if (!session) {\n handleError(\"No active browser session\");\n }\n\n const state = await client.getState(session.id);\n\n if (parent?.json) {\n console.log(JSON.stringify(state, null, 2));\n } else {\n console.log(\"Browser State:\");\n console.log(` URL: ${state.url}`);\n console.log(` Title: ${state.title}`);\n console.log(` Session ID: ${state.sessionId}`);\n }\n });\n\n // Solve captcha command\n browser\n .command(\"solve-captcha\")\n .description(\"Attempt to solve a captcha on the page\")\n .action(async (_opts, cmd) => {\n const parent = cmd.parent?.opts() as { json?: boolean } | undefined;\n const service = requireService(ctx);\n const client = service.getClient();\n\n const session = await service.getCurrentSession();\n if (!session) {\n handleError(\"No active browser session\");\n }\n\n const result = await client.solveCaptcha(session.id);\n\n if (parent?.json) {\n console.log(JSON.stringify(result.data ?? { attempted: true }, null, 2));\n } else {\n console.log(\"Captcha solve attempted\");\n if (result.data) {\n console.log(JSON.stringify(result.data, null, 2));\n }\n }\n });\n\n // Health command\n browser\n .command(\"health\")\n .description(\"Check browser server health\")\n .action(async (_opts, cmd) => {\n const parent = cmd.parent?.opts() as { json?: boolean } | undefined;\n const service = getBrowserService(ctx);\n\n let healthy = false;\n if (service) {\n const client = service.getClient();\n healthy = await client.health();\n }\n\n if (parent?.json) {\n console.log(JSON.stringify({ healthy, serviceAvailable: !!service }, null, 2));\n } else {\n console.log(`Browser server health: ${healthy ? \"OK\" : \"UNHEALTHY\"}`);\n console.log(`Service available: ${!!service}`);\n }\n });\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -12,6 +12,7 @@ export * from "./types.js";
12
12
  export * from "./utils/index.js";
13
13
  export { BrowserService, Session, BrowserWebSocketClient, BrowserProcessManager };
14
14
  export { browserNavigateAction, browserClickAction, browserTypeAction, browserSelectAction, browserExtractAction, browserScreenshotAction, };
15
+ import "./cli/index.js";
15
16
  export declare const browserPlugin: Plugin;
16
17
  export default browserPlugin;
17
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyB,MAAM,EAAmC,MAAM,eAAe,CAAC;AAGpG,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAExE,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,CAAC;AAClF,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,GACxB,CAAC;AAsEF,eAAO,MAAM,aAAa,EAAE,MA+C3B,CAAC;AAEF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyB,MAAM,EAAmC,MAAM,eAAe,CAAC;AAGpG,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAExE,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,CAAC;AAClF,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,GACxB,CAAC;AAuEF,OAAO,gBAAgB,CAAC;AAExB,eAAO,MAAM,aAAa,EAAE,MA+C3B,CAAC;AAEF,eAAe,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -73,6 +73,8 @@ const browserStateProvider = {
73
73
  }
74
74
  },
75
75
  };
76
+ // CLI self-registration - importing this module triggers CLI command registration
77
+ import "./cli/index.js";
76
78
  export const browserPlugin = {
77
79
  name: "plugin-browser",
78
80
  description: "Browser automation plugin",
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IAgentRuntime, Memory, Plugin, Provider, ProviderResult, State } from \"@elizaos/core\";\nimport { logger, ServiceType } from \"@elizaos/core\";\nimport { z } from \"zod\";\nimport { browserClickAction } from \"./actions/click.js\";\nimport { browserExtractAction } from \"./actions/extract.js\";\nimport { browserNavigateAction } from \"./actions/navigate.js\";\nimport { browserScreenshotAction } from \"./actions/screenshot.js\";\nimport { browserSelectAction } from \"./actions/select.js\";\nimport { browserTypeAction } from \"./actions/type.js\";\nimport { BrowserService, Session } from \"./services/browser-service.js\";\nimport { BrowserProcessManager } from \"./services/process-manager.js\";\nimport { BrowserWebSocketClient } from \"./services/websocket-client.js\";\n\nexport * from \"./types.js\";\nexport * from \"./utils/index.js\";\nexport { BrowserService, Session, BrowserWebSocketClient, BrowserProcessManager };\nexport {\n browserNavigateAction,\n browserClickAction,\n browserTypeAction,\n browserSelectAction,\n browserExtractAction,\n browserScreenshotAction,\n};\nconst configSchema = z.object({\n BROWSERBASE_API_KEY: z.string().optional(),\n BROWSERBASE_PROJECT_ID: z.string().optional(),\n OPENAI_API_KEY: z.string().optional(),\n ANTHROPIC_API_KEY: z.string().optional(),\n OLLAMA_BASE_URL: z.string().optional(),\n OLLAMA_MODEL: z.string().optional(),\n BROWSER_HEADLESS: z\n .string()\n .transform((val: string) => val === \"true\")\n .optional()\n .default(true),\n CAPSOLVER_API_KEY: z.string().optional(),\n BROWSER_SERVER_PORT: z.string().optional().default(\"3456\"),\n});\n\nconst browserStateProvider: Provider = {\n name: \"BROWSER_STATE\",\n description: \"Provides current browser state information\",\n\n get: async (\n runtime: IAgentRuntime,\n _message: Memory,\n _state?: State\n ): Promise<ProviderResult> => {\n const service = runtime.getService<BrowserService>(ServiceType.BROWSER);\n const session = await service?.getCurrentSession();\n\n if (!session || !service) {\n return {\n text: \"No active browser session\",\n values: {\n hasSession: false,\n },\n data: {},\n };\n }\n\n try {\n const client = service.getClient();\n const state = await client.getState(session.id);\n\n return {\n text: `Current browser page: \"${state.title}\" at ${state.url}`,\n values: {\n hasSession: true,\n url: state.url,\n title: state.title,\n },\n data: {\n sessionId: session.id,\n createdAt: session.createdAt.toISOString(),\n },\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(`Error getting browser state: ${errorMessage}`);\n return {\n text: \"Error getting browser state\",\n values: {\n hasSession: true,\n error: true,\n },\n data: {},\n };\n }\n },\n};\n\nexport const browserPlugin: Plugin = {\n name: \"plugin-browser\",\n description: \"Browser automation plugin\",\n config: {\n BROWSERBASE_API_KEY: process.env.BROWSERBASE_API_KEY ?? null,\n BROWSERBASE_PROJECT_ID: process.env.BROWSERBASE_PROJECT_ID ?? null,\n OPENAI_API_KEY: process.env.OPENAI_API_KEY ?? null,\n ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY ?? null,\n OLLAMA_BASE_URL: process.env.OLLAMA_BASE_URL ?? null,\n OLLAMA_MODEL: process.env.OLLAMA_MODEL ?? null,\n BROWSER_HEADLESS: process.env.BROWSER_HEADLESS ?? \"true\",\n CAPSOLVER_API_KEY: process.env.CAPSOLVER_API_KEY ?? null,\n BROWSER_SERVER_PORT: process.env.BROWSER_SERVER_PORT ?? \"3456\",\n },\n async init(config: Record<string, string | null>, _runtime: IAgentRuntime) {\n logger.info(\"Initializing browser automation plugin\");\n try {\n const validatedConfig = await configSchema.parseAsync(config);\n\n for (const [key, value] of Object.entries(validatedConfig)) {\n if (value !== undefined && value !== null) {\n process.env[key] = String(value);\n }\n }\n\n logger.info(\"Browser plugin initialized successfully\");\n } catch (error) {\n if (error && typeof error === \"object\" && \"issues\" in error) {\n const zodError = error as { issues?: Array<{ message: string }> };\n if (Array.isArray(zodError.issues)) {\n const errorMessages = zodError.issues.map((e) => e.message).join(\", \");\n throw new Error(`Invalid plugin configuration: ${errorMessages}`);\n }\n }\n throw error;\n }\n },\n services: [BrowserService],\n actions: [\n browserNavigateAction,\n browserClickAction,\n browserTypeAction,\n browserSelectAction,\n browserExtractAction,\n browserScreenshotAction,\n ],\n providers: [browserStateProvider],\n};\n\nexport default browserPlugin;\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IAgentRuntime, Memory, Plugin, Provider, ProviderResult, State } from \"@elizaos/core\";\nimport { logger, ServiceType } from \"@elizaos/core\";\nimport { z } from \"zod\";\nimport { browserClickAction } from \"./actions/click.js\";\nimport { browserExtractAction } from \"./actions/extract.js\";\nimport { browserNavigateAction } from \"./actions/navigate.js\";\nimport { browserScreenshotAction } from \"./actions/screenshot.js\";\nimport { browserSelectAction } from \"./actions/select.js\";\nimport { browserTypeAction } from \"./actions/type.js\";\nimport { BrowserService, Session } from \"./services/browser-service.js\";\nimport { BrowserProcessManager } from \"./services/process-manager.js\";\nimport { BrowserWebSocketClient } from \"./services/websocket-client.js\";\n\nexport * from \"./types.js\";\nexport * from \"./utils/index.js\";\nexport { BrowserService, Session, BrowserWebSocketClient, BrowserProcessManager };\nexport {\n browserNavigateAction,\n browserClickAction,\n browserTypeAction,\n browserSelectAction,\n browserExtractAction,\n browserScreenshotAction,\n};\nconst configSchema = z.object({\n BROWSERBASE_API_KEY: z.string().optional(),\n BROWSERBASE_PROJECT_ID: z.string().optional(),\n OPENAI_API_KEY: z.string().optional(),\n ANTHROPIC_API_KEY: z.string().optional(),\n OLLAMA_BASE_URL: z.string().optional(),\n OLLAMA_MODEL: z.string().optional(),\n BROWSER_HEADLESS: z\n .string()\n .transform((val: string) => val === \"true\")\n .optional()\n .default(true),\n CAPSOLVER_API_KEY: z.string().optional(),\n BROWSER_SERVER_PORT: z.string().optional().default(\"3456\"),\n});\n\nconst browserStateProvider: Provider = {\n name: \"BROWSER_STATE\",\n description: \"Provides current browser state information\",\n\n get: async (\n runtime: IAgentRuntime,\n _message: Memory,\n _state?: State\n ): Promise<ProviderResult> => {\n const service = runtime.getService<BrowserService>(ServiceType.BROWSER);\n const session = await service?.getCurrentSession();\n\n if (!session || !service) {\n return {\n text: \"No active browser session\",\n values: {\n hasSession: false,\n },\n data: {},\n };\n }\n\n try {\n const client = service.getClient();\n const state = await client.getState(session.id);\n\n return {\n text: `Current browser page: \"${state.title}\" at ${state.url}`,\n values: {\n hasSession: true,\n url: state.url,\n title: state.title,\n },\n data: {\n sessionId: session.id,\n createdAt: session.createdAt.toISOString(),\n },\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(`Error getting browser state: ${errorMessage}`);\n return {\n text: \"Error getting browser state\",\n values: {\n hasSession: true,\n error: true,\n },\n data: {},\n };\n }\n },\n};\n\n// CLI self-registration - importing this module triggers CLI command registration\nimport \"./cli/index.js\";\n\nexport const browserPlugin: Plugin = {\n name: \"plugin-browser\",\n description: \"Browser automation plugin\",\n config: {\n BROWSERBASE_API_KEY: process.env.BROWSERBASE_API_KEY ?? null,\n BROWSERBASE_PROJECT_ID: process.env.BROWSERBASE_PROJECT_ID ?? null,\n OPENAI_API_KEY: process.env.OPENAI_API_KEY ?? null,\n ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY ?? null,\n OLLAMA_BASE_URL: process.env.OLLAMA_BASE_URL ?? null,\n OLLAMA_MODEL: process.env.OLLAMA_MODEL ?? null,\n BROWSER_HEADLESS: process.env.BROWSER_HEADLESS ?? \"true\",\n CAPSOLVER_API_KEY: process.env.CAPSOLVER_API_KEY ?? null,\n BROWSER_SERVER_PORT: process.env.BROWSER_SERVER_PORT ?? \"3456\",\n },\n async init(config: Record<string, string | null>, _runtime: IAgentRuntime) {\n logger.info(\"Initializing browser automation plugin\");\n try {\n const validatedConfig = await configSchema.parseAsync(config);\n\n for (const [key, value] of Object.entries(validatedConfig)) {\n if (value !== undefined && value !== null) {\n process.env[key] = String(value);\n }\n }\n\n logger.info(\"Browser plugin initialized successfully\");\n } catch (error) {\n if (error && typeof error === \"object\" && \"issues\" in error) {\n const zodError = error as { issues?: Array<{ message: string }> };\n if (Array.isArray(zodError.issues)) {\n const errorMessages = zodError.issues.map((e) => e.message).join(\", \");\n throw new Error(`Invalid plugin configuration: ${errorMessages}`);\n }\n }\n throw error;\n }\n },\n services: [BrowserService],\n actions: [\n browserNavigateAction,\n browserClickAction,\n browserTypeAction,\n browserSelectAction,\n browserExtractAction,\n browserScreenshotAction,\n ],\n providers: [browserStateProvider],\n};\n\nexport default browserPlugin;\n"]}
@@ -5,6 +5,7 @@ export declare class BrowserProcessManager {
5
5
  private binaryPath;
6
6
  constructor(serverPort?: number);
7
7
  private getBinaryName;
8
+ private findPluginRoot;
8
9
  private findBinary;
9
10
  start(): Promise<void>;
10
11
  private waitForServer;
@@ -1 +1 @@
1
- {"version":3,"file":"process-manager.d.ts","sourceRoot":"","sources":["../../src/services/process-manager.ts"],"names":[],"mappings":"AAOA,qBAAa,qBAAqB;IAKpB,OAAO,CAAC,UAAU;IAJ9B,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAuB;gBAErB,UAAU,GAAE,MAAa;IAI7C,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,UAAU;IA+CZ,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YA6Ed,aAAa;IAqCrB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB3B,eAAe,IAAI,OAAO;IAI1B,YAAY,IAAI,MAAM;CAGvB"}
1
+ {"version":3,"file":"process-manager.d.ts","sourceRoot":"","sources":["../../src/services/process-manager.ts"],"names":[],"mappings":"AAOA,qBAAa,qBAAqB;IAKpB,OAAO,CAAC,UAAU;IAJ9B,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAuB;gBAErB,UAAU,GAAE,MAAa;IAI7C,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,cAAc;IAgBtB,OAAO,CAAC,UAAU;IA+DZ,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YA6Ed,aAAa;IAqCrB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB3B,eAAe,IAAI,OAAO;IAI1B,YAAY,IAAI,MAAM;CAGvB"}
@@ -22,8 +22,25 @@ export class BrowserProcessManager {
22
22
  fallback: `browser-server-${platformName}${ext}`,
23
23
  };
24
24
  }
25
+ findPluginRoot() {
26
+ const moduleDir = dirname(fileURLToPath(import.meta.url));
27
+ // Walk up from moduleDir until we find the plugin-browser root
28
+ // (identified by having a stagehand-server/ directory or the root package.json)
29
+ let dir = moduleDir;
30
+ for (let i = 0; i < 6; i++) {
31
+ if (existsSync(join(dir, "stagehand-server"))) {
32
+ return dir;
33
+ }
34
+ const parent = dirname(dir);
35
+ if (parent === dir)
36
+ break;
37
+ dir = parent;
38
+ }
39
+ return dirname(moduleDir); // fallback
40
+ }
25
41
  findBinary() {
26
42
  const moduleDir = dirname(fileURLToPath(import.meta.url));
43
+ const pluginRoot = this.findPluginRoot();
27
44
  const isDocker = process.env.DOCKER_CONTAINER === "true" || existsSync("/.dockerenv");
28
45
  const binaryNames = this.getBinaryName();
29
46
  const possiblePaths = [
@@ -36,6 +53,9 @@ export class BrowserProcessManager {
36
53
  `/app/binaries/${binaryNames.fallback}`,
37
54
  ]
38
55
  : []),
56
+ // Built stagehand-server (relative to plugin root)
57
+ join(pluginRoot, "stagehand-server/dist/index.js"),
58
+ // Legacy paths (relative to moduleDir) for backwards compatibility
39
59
  ...(!isDocker ? [join(moduleDir, "../server/dist/index.js")] : []),
40
60
  join(moduleDir, "../server/binaries", binaryNames.primary),
41
61
  join(moduleDir, "../server/binaries", binaryNames.fallback),
@@ -53,6 +73,13 @@ export class BrowserProcessManager {
53
73
  return path;
54
74
  }
55
75
  }
76
+ // Fallback: try running stagehand-server from source with tsx
77
+ const stagehandSrcPath = join(pluginRoot, "stagehand-server/src/index.ts");
78
+ if (existsSync(stagehandSrcPath)) {
79
+ logger.warn("No compiled browser server found, will try to run stagehand-server from source with tsx");
80
+ return stagehandSrcPath;
81
+ }
82
+ // Legacy source fallback
56
83
  const srcPath = join(moduleDir, "../server/src/index.ts");
57
84
  if (existsSync(srcPath)) {
58
85
  logger.warn("No compiled binary found, will try to run from source with tsx");
@@ -60,6 +87,7 @@ export class BrowserProcessManager {
60
87
  }
61
88
  logger.error("Could not find browser server binary or source files");
62
89
  logger.error(`Searched paths: ${possiblePaths.join(", ")}`);
90
+ logger.error(`Also checked stagehand-server source at: ${stagehandSrcPath}`);
63
91
  return null;
64
92
  }
65
93
  async start() {
@@ -1 +1 @@
1
- {"version":3,"file":"process-manager.js","sourceRoot":"","sources":["../../src/services/process-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ChildProcess, spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { platform } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { logger } from \"@elizaos/core\";\n\nexport class BrowserProcessManager {\n private process: ChildProcess | null = null;\n private isRunning = false;\n private binaryPath: string | null = null;\n\n constructor(private serverPort: number = 3456) {\n this.binaryPath = this.findBinary();\n }\n\n private getBinaryName(): { primary: string; fallback: string } {\n const platformName = platform();\n const arch = process.arch;\n const ext = platformName === \"win32\" ? \".exe\" : \"\";\n\n return {\n primary: `browser-server-${platformName}-${arch}${ext}`,\n fallback: `browser-server-${platformName}${ext}`,\n };\n }\n\n private findBinary(): string | null {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const isDocker = process.env.DOCKER_CONTAINER === \"true\" || existsSync(\"/.dockerenv\");\n const binaryNames = this.getBinaryName();\n\n const possiblePaths = [\n ...(isDocker\n ? [\n \"/usr/local/bin/browser-server\",\n \"/usr/local/bin/browser-server-linux\",\n \"/app/browser-server\",\n `/app/binaries/${binaryNames.primary}`,\n `/app/binaries/${binaryNames.fallback}`,\n ]\n : []),\n\n ...(!isDocker ? [join(moduleDir, \"../server/dist/index.js\")] : []),\n join(moduleDir, \"../server/binaries\", binaryNames.primary),\n join(moduleDir, \"../server/binaries\", binaryNames.fallback),\n join(moduleDir, \"../../../browser-server\", binaryNames.primary),\n join(moduleDir, \"../../../browser-server\", binaryNames.fallback),\n join(moduleDir, \"../../.bin\", \"browser-server\"),\n join(moduleDir, \"../server/dist/index.js\"),\n\n ...(isDocker\n ? [\"/app/packages/plugin-browser/server/dist/index.js\", \"/app/browser-server/dist/index.js\"]\n : []),\n ];\n\n for (const path of possiblePaths) {\n if (existsSync(path)) {\n logger.info(`Found browser server at: ${path}`);\n return path;\n }\n }\n\n const srcPath = join(moduleDir, \"../server/src/index.ts\");\n if (existsSync(srcPath)) {\n logger.warn(\"No compiled binary found, will try to run from source with tsx\");\n return srcPath;\n }\n\n logger.error(\"Could not find browser server binary or source files\");\n logger.error(`Searched paths: ${possiblePaths.join(\", \")}`);\n return null;\n }\n\n async start(): Promise<void> {\n if (this.isRunning) {\n logger.warn(\"Browser server is already running\");\n return;\n }\n\n if (!this.binaryPath) {\n throw new Error(\"Browser server binary not found - please ensure server is built\");\n }\n\n const binaryPath = this.binaryPath;\n\n return new Promise((resolve, reject) => {\n const env = {\n ...process.env,\n BROWSER_SERVER_PORT: this.serverPort.toString(),\n NODE_ENV: process.env.NODE_ENV ?? \"production\",\n BROWSERBASE_API_KEY: process.env.BROWSERBASE_API_KEY,\n BROWSERBASE_PROJECT_ID: process.env.BROWSERBASE_PROJECT_ID,\n OPENAI_API_KEY: process.env.OPENAI_API_KEY,\n ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,\n BROWSER_HEADLESS: process.env.BROWSER_HEADLESS,\n CAPSOLVER_API_KEY: process.env.CAPSOLVER_API_KEY,\n OLLAMA_BASE_URL: process.env.OLLAMA_BASE_URL ?? \"http://ollama:11434\",\n OLLAMA_MODEL: process.env.OLLAMA_MODEL ?? \"llama3.2-vision\",\n DISPLAY: process.env.DISPLAY ?? \":99\",\n };\n\n const isBinary = !binaryPath.endsWith(\".js\") && !binaryPath.endsWith(\".ts\");\n const isTypeScript = binaryPath.endsWith(\".ts\");\n\n if (isBinary) {\n this.process = spawn(binaryPath, [], { env });\n } else if (isTypeScript) {\n const tsxPath = require.resolve(\"tsx/cli\", { paths: [process.cwd()] });\n this.process = spawn(\"node\", [tsxPath, binaryPath], { env });\n } else {\n this.process = spawn(\"node\", [binaryPath], { env });\n }\n\n this.process.stdout?.on(\"data\", (data: Buffer) => {\n const message = data.toString().trim();\n logger.debug(`[BrowserServer] ${message}`);\n\n if (message.includes(\"listening on port\")) {\n this.isRunning = true;\n resolve();\n }\n });\n\n this.process.stderr?.on(\"data\", (data: Buffer) => {\n logger.error(`[BrowserServer Error] ${data.toString()}`);\n });\n\n this.process.on(\"error\", (error: Error) => {\n logger.error(`Failed to start browser server: ${error.message}`);\n this.isRunning = false;\n reject(error);\n });\n\n this.process.on(\"exit\", (code) => {\n logger.info(`Browser server exited with code ${code}`);\n this.isRunning = false;\n });\n\n this.waitForServer()\n .then(() => resolve())\n .catch((error) => {\n this.isRunning = false;\n if (this.process) {\n this.process.kill(\"SIGTERM\");\n }\n reject(error);\n });\n });\n }\n\n private async waitForServer(): Promise<void> {\n const maxAttempts = 30;\n const delay = 1000;\n\n for (let i = 0; i < maxAttempts; i++) {\n try {\n const ws = require(\"ws\");\n const wsConnection = new ws(`ws://localhost:${this.serverPort}`);\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n wsConnection.close();\n reject(new Error(\"Connection timeout\"));\n }, 5000);\n\n wsConnection.on(\"open\", () => {\n clearTimeout(timeout);\n wsConnection.close();\n resolve();\n });\n\n wsConnection.on(\"error\", (error: Error) => {\n clearTimeout(timeout);\n reject(error);\n });\n });\n\n logger.info(\"Browser server is ready\");\n return;\n } catch {}\n\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n\n throw new Error(\"Browser server failed to start\");\n }\n\n async stop(): Promise<void> {\n if (!this.process || !this.isRunning) {\n return;\n }\n\n return new Promise((resolve) => {\n this.process?.on(\"exit\", () => {\n this.isRunning = false;\n resolve();\n });\n\n this.process?.kill(\"SIGTERM\");\n\n setTimeout(() => {\n if (this.isRunning && this.process) {\n this.process.kill(\"SIGKILL\");\n }\n }, 5000);\n });\n }\n\n isServerRunning(): boolean {\n return this.isRunning;\n }\n\n getServerUrl(): string {\n return `ws://localhost:${this.serverPort}`;\n }\n}\n"]}
1
+ {"version":3,"file":"process-manager.js","sourceRoot":"","sources":["../../src/services/process-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ChildProcess, spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { platform } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { logger } from \"@elizaos/core\";\n\nexport class BrowserProcessManager {\n private process: ChildProcess | null = null;\n private isRunning = false;\n private binaryPath: string | null = null;\n\n constructor(private serverPort: number = 3456) {\n this.binaryPath = this.findBinary();\n }\n\n private getBinaryName(): { primary: string; fallback: string } {\n const platformName = platform();\n const arch = process.arch;\n const ext = platformName === \"win32\" ? \".exe\" : \"\";\n\n return {\n primary: `browser-server-${platformName}-${arch}${ext}`,\n fallback: `browser-server-${platformName}${ext}`,\n };\n }\n\n private findPluginRoot(): string {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n // Walk up from moduleDir until we find the plugin-browser root\n // (identified by having a stagehand-server/ directory or the root package.json)\n let dir = moduleDir;\n for (let i = 0; i < 6; i++) {\n if (existsSync(join(dir, \"stagehand-server\"))) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return dirname(moduleDir); // fallback\n }\n\n private findBinary(): string | null {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const pluginRoot = this.findPluginRoot();\n const isDocker = process.env.DOCKER_CONTAINER === \"true\" || existsSync(\"/.dockerenv\");\n const binaryNames = this.getBinaryName();\n\n const possiblePaths = [\n ...(isDocker\n ? [\n \"/usr/local/bin/browser-server\",\n \"/usr/local/bin/browser-server-linux\",\n \"/app/browser-server\",\n `/app/binaries/${binaryNames.primary}`,\n `/app/binaries/${binaryNames.fallback}`,\n ]\n : []),\n\n // Built stagehand-server (relative to plugin root)\n join(pluginRoot, \"stagehand-server/dist/index.js\"),\n\n // Legacy paths (relative to moduleDir) for backwards compatibility\n ...(!isDocker ? [join(moduleDir, \"../server/dist/index.js\")] : []),\n join(moduleDir, \"../server/binaries\", binaryNames.primary),\n join(moduleDir, \"../server/binaries\", binaryNames.fallback),\n join(moduleDir, \"../../../browser-server\", binaryNames.primary),\n join(moduleDir, \"../../../browser-server\", binaryNames.fallback),\n join(moduleDir, \"../../.bin\", \"browser-server\"),\n join(moduleDir, \"../server/dist/index.js\"),\n\n ...(isDocker\n ? [\"/app/packages/plugin-browser/server/dist/index.js\", \"/app/browser-server/dist/index.js\"]\n : []),\n ];\n\n for (const path of possiblePaths) {\n if (existsSync(path)) {\n logger.info(`Found browser server at: ${path}`);\n return path;\n }\n }\n\n // Fallback: try running stagehand-server from source with tsx\n const stagehandSrcPath = join(pluginRoot, \"stagehand-server/src/index.ts\");\n if (existsSync(stagehandSrcPath)) {\n logger.warn(\n \"No compiled browser server found, will try to run stagehand-server from source with tsx\"\n );\n return stagehandSrcPath;\n }\n\n // Legacy source fallback\n const srcPath = join(moduleDir, \"../server/src/index.ts\");\n if (existsSync(srcPath)) {\n logger.warn(\"No compiled binary found, will try to run from source with tsx\");\n return srcPath;\n }\n\n logger.error(\"Could not find browser server binary or source files\");\n logger.error(`Searched paths: ${possiblePaths.join(\", \")}`);\n logger.error(`Also checked stagehand-server source at: ${stagehandSrcPath}`);\n return null;\n }\n\n async start(): Promise<void> {\n if (this.isRunning) {\n logger.warn(\"Browser server is already running\");\n return;\n }\n\n if (!this.binaryPath) {\n throw new Error(\"Browser server binary not found - please ensure server is built\");\n }\n\n const binaryPath = this.binaryPath;\n\n return new Promise((resolve, reject) => {\n const env = {\n ...process.env,\n BROWSER_SERVER_PORT: this.serverPort.toString(),\n NODE_ENV: process.env.NODE_ENV ?? \"production\",\n BROWSERBASE_API_KEY: process.env.BROWSERBASE_API_KEY,\n BROWSERBASE_PROJECT_ID: process.env.BROWSERBASE_PROJECT_ID,\n OPENAI_API_KEY: process.env.OPENAI_API_KEY,\n ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,\n BROWSER_HEADLESS: process.env.BROWSER_HEADLESS,\n CAPSOLVER_API_KEY: process.env.CAPSOLVER_API_KEY,\n OLLAMA_BASE_URL: process.env.OLLAMA_BASE_URL ?? \"http://ollama:11434\",\n OLLAMA_MODEL: process.env.OLLAMA_MODEL ?? \"llama3.2-vision\",\n DISPLAY: process.env.DISPLAY ?? \":99\",\n };\n\n const isBinary = !binaryPath.endsWith(\".js\") && !binaryPath.endsWith(\".ts\");\n const isTypeScript = binaryPath.endsWith(\".ts\");\n\n if (isBinary) {\n this.process = spawn(binaryPath, [], { env });\n } else if (isTypeScript) {\n const tsxPath = require.resolve(\"tsx/cli\", { paths: [process.cwd()] });\n this.process = spawn(\"node\", [tsxPath, binaryPath], { env });\n } else {\n this.process = spawn(\"node\", [binaryPath], { env });\n }\n\n this.process.stdout?.on(\"data\", (data: Buffer) => {\n const message = data.toString().trim();\n logger.debug(`[BrowserServer] ${message}`);\n\n if (message.includes(\"listening on port\")) {\n this.isRunning = true;\n resolve();\n }\n });\n\n this.process.stderr?.on(\"data\", (data: Buffer) => {\n logger.error(`[BrowserServer Error] ${data.toString()}`);\n });\n\n this.process.on(\"error\", (error: Error) => {\n logger.error(`Failed to start browser server: ${error.message}`);\n this.isRunning = false;\n reject(error);\n });\n\n this.process.on(\"exit\", (code) => {\n logger.info(`Browser server exited with code ${code}`);\n this.isRunning = false;\n });\n\n this.waitForServer()\n .then(() => resolve())\n .catch((error) => {\n this.isRunning = false;\n if (this.process) {\n this.process.kill(\"SIGTERM\");\n }\n reject(error);\n });\n });\n }\n\n private async waitForServer(): Promise<void> {\n const maxAttempts = 30;\n const delay = 1000;\n\n for (let i = 0; i < maxAttempts; i++) {\n try {\n const ws = require(\"ws\");\n const wsConnection = new ws(`ws://localhost:${this.serverPort}`);\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n wsConnection.close();\n reject(new Error(\"Connection timeout\"));\n }, 5000);\n\n wsConnection.on(\"open\", () => {\n clearTimeout(timeout);\n wsConnection.close();\n resolve();\n });\n\n wsConnection.on(\"error\", (error: Error) => {\n clearTimeout(timeout);\n reject(error);\n });\n });\n\n logger.info(\"Browser server is ready\");\n return;\n } catch {}\n\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n\n throw new Error(\"Browser server failed to start\");\n }\n\n async stop(): Promise<void> {\n if (!this.process || !this.isRunning) {\n return;\n }\n\n return new Promise((resolve) => {\n this.process?.on(\"exit\", () => {\n this.isRunning = false;\n resolve();\n });\n\n this.process?.kill(\"SIGTERM\");\n\n setTimeout(() => {\n if (this.isRunning && this.process) {\n this.process.kill(\"SIGKILL\");\n }\n }, 5000);\n });\n }\n\n isServerRunning(): boolean {\n return this.isRunning;\n }\n\n getServerUrl(): string {\n return `ws://localhost:${this.serverPort}`;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elizaos/plugin-browser",
3
3
  "description": "Browser automation plugin for ElizaOS - enables AI agents to browse websites, interact with elements, and extract data",
4
- "version": "2.0.0-alpha.1",
4
+ "version": "2.0.0-alpha.4",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -37,17 +37,18 @@
37
37
  "package.json"
38
38
  ],
39
39
  "dependencies": {
40
- "ws": "^8.18.0",
40
+ "@elizaos/plugin-cli": "2.0.0-alpha.3",
41
41
  "axios": "^1.7.7",
42
- "zod": "^4.3.5"
42
+ "ws": "^8.18.0",
43
+ "zod": "^4.3.6"
43
44
  },
44
45
  "peerDependencies": {
45
- "@elizaos/core": "workspace:*"
46
+ "@elizaos/core": "2.0.0-alpha.3"
46
47
  },
47
48
  "devDependencies": {
49
+ "@biomejs/biome": "^2.3.11",
48
50
  "@types/ws": "^8.5.10",
49
- "typescript": "^5.9.3",
50
- "@biomejs/biome": "^2.3.11"
51
+ "typescript": "^5.9.3"
51
52
  },
52
53
  "scripts": {
53
54
  "dev": "bun --hot build.ts",
@@ -57,7 +58,9 @@
57
58
  "clean": "rm -rf dist .turbo",
58
59
  "lint:check": "bunx @biomejs/biome check .",
59
60
  "build": "bun run build.ts",
60
- "build:ts": "bun run build.ts"
61
+ "build:ts": "bun run build.ts",
62
+ "format": "bunx @biomejs/biome format --write .",
63
+ "format:check": "bunx @biomejs/biome format ."
61
64
  },
62
65
  "agentConfig": {
63
66
  "pluginType": "elizaos:plugin:1.0.0",
@@ -96,5 +99,14 @@
96
99
  },
97
100
  "publishConfig": {
98
101
  "access": "public"
102
+ },
103
+ "milaidy": {
104
+ "platforms": [
105
+ "node"
106
+ ],
107
+ "runtime": "node",
108
+ "platformDetails": {
109
+ "node": "Node.js only (platform: node)"
110
+ }
99
111
  }
100
112
  }