agentic-browser 2.6.1 → 2.6.2
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/AGENTS.md +25 -19
- package/README.md +1 -1
- package/dist/cli/index.mjs +38 -39
- package/dist/index.d.mts +85 -98
- package/dist/index.mjs +1 -2
- package/dist/mcp/index.d.mts +1 -4
- package/dist/mcp/index.mjs +47 -18
- package/dist/{runtime-BzdbtFF4.mjs → runtime-Bo7FmRYk.mjs} +359 -116
- package/dist/{setup-DUAjdbQ3.mjs → setup-DwFaZOPf.mjs} +13 -6
- package/package.json +21 -19
package/AGENTS.md
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
## Quick Reference
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
pnpm build # tsdown (~20ms)
|
|
7
|
+
pnpm typecheck # tsc --noEmit
|
|
8
|
+
pnpm lint # oxlint
|
|
9
|
+
pnpm lint:fix # oxlint --fix
|
|
10
|
+
pnpm format # oxfmt --write
|
|
11
|
+
pnpm test # vitest run
|
|
12
|
+
pnpm test:watch # vitest
|
|
13
|
+
pnpm docs:dev # vocs dev server
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
## Architecture
|
|
@@ -29,7 +29,7 @@ src/
|
|
|
29
29
|
commands/agent.ts — Stateful agent commands (auto-restart, retry, session persistence)
|
|
30
30
|
commands/*.ts — Low-level CLI command handlers
|
|
31
31
|
mcp/
|
|
32
|
-
index.ts — MCP server (stdio transport,
|
|
32
|
+
index.ts — MCP server (stdio transport, tools wrapping AgenticBrowserCore)
|
|
33
33
|
session/
|
|
34
34
|
browser-controller.ts — BrowserController interface + ChromeCdpBrowserController (CDP WebSocket)
|
|
35
35
|
session-manager.ts — Orchestrates sessions, commands, memory recording
|
|
@@ -68,7 +68,7 @@ AgenticBrowserCore → ControlApi → SessionManager → BrowserController (CDP)
|
|
|
68
68
|
|
|
69
69
|
- **ESM-only**: `"type": "module"`, use `.js` extensions in all TypeScript imports
|
|
70
70
|
- **Zod v4**: `import { z } from "zod"` — `z.record()` requires key+value args
|
|
71
|
-
- **Commander.js
|
|
71
|
+
- **Commander.js v15**: colon-namespaced commands (`session:start`, `memory:search`)
|
|
72
72
|
- **CLI output**: exactly one JSON line to `stdout`, errors to `stderr`
|
|
73
73
|
- **Types**: interfaces for public contracts, type aliases for unions/inferred
|
|
74
74
|
- **No console.log in MCP server**: use `process.stderr.write()` for debug output
|
|
@@ -111,21 +111,27 @@ AgenticBrowserCore → ControlApi → SessionManager → BrowserController (CDP)
|
|
|
111
111
|
- `AGENTIC_BROWSER_DIR` — base dir for sessions/memory/events (default: `~/.agentic-browser`)
|
|
112
112
|
- `AGENTIC_BROWSER_CHROME_EXECUTABLE_PATH` — explicit Chrome path (auto-discovered if not set)
|
|
113
113
|
- `AGENTIC_BROWSER_CDP_URL` — connect to an already-running Chrome via CDP (e.g. `http://127.0.0.1:9222`)
|
|
114
|
+
- `AGENTIC_BROWSER_ALLOW_FILE_URLS` — allow `file:` URLs in navigate (`true` or `1`); default is http(s) and about:blank only
|
|
114
115
|
- `AGENTIC_BROWSER_USER_PROFILE` — use real Chrome profile (`default`, `true`, or absolute path)
|
|
116
|
+
- `AGENTIC_BROWSER_CHROME_PATH` — alias of `AGENTIC_BROWSER_CHROME_EXECUTABLE_PATH`
|
|
117
|
+
- `AGENTIC_BROWSER_HEADLESS` — `true` or `1` to launch Chrome headless
|
|
118
|
+
- `AGENTIC_BROWSER_USER_AGENT` — override the browser user agent
|
|
115
119
|
|
|
116
120
|
## MCP Server
|
|
117
121
|
|
|
118
122
|
Subcommand: `agentic-browser mcp` (stdio transport). Setup: `agentic-browser setup`. Tools:
|
|
119
123
|
|
|
120
|
-
| Tool
|
|
121
|
-
|
|
|
122
|
-
| `browser_start_session`
|
|
123
|
-
| `browser_navigate`
|
|
124
|
-
| `browser_interact`
|
|
125
|
-
| `browser_get_content`
|
|
126
|
-
| `browser_get_elements`
|
|
127
|
-
| `browser_search_memory`
|
|
128
|
-
| `browser_stop_session`
|
|
124
|
+
| Tool | Purpose |
|
|
125
|
+
| ------------------------- | --------------------------------------------------------------------------------------------------------- |
|
|
126
|
+
| `browser_start_session` | Start Chrome, return sessionId |
|
|
127
|
+
| `browser_navigate` | Navigate to URL |
|
|
128
|
+
| `browser_interact` | click / type / press / waitFor / scroll / hover / select / toggle / goBack / goForward / refresh / dialog |
|
|
129
|
+
| `browser_get_content` | Get page title / text / html |
|
|
130
|
+
| `browser_get_elements` | Discover interactive elements |
|
|
131
|
+
| `browser_search_memory` | Search task memory |
|
|
132
|
+
| `browser_stop_session` | Stop Chrome session |
|
|
133
|
+
| `browser_dismiss_cookies` | Dismiss cookie or consent banner |
|
|
134
|
+
| `browser_screenshot` | Screenshot as base64 (jpeg or png, optional full page) |
|
|
129
135
|
|
|
130
136
|
## For Browser Automation Tasks
|
|
131
137
|
|
package/README.md
CHANGED
package/dist/cli/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { r as createCliRuntime } from "../runtime-
|
|
2
|
+
import { a as isConnectionError, o as ensurePrivateDir, r as createCliRuntime, s as writePrivateFileSync } from "../runtime-Bo7FmRYk.mjs";
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import crypto from "node:crypto";
|
|
6
6
|
import { Command } from "commander";
|
|
7
|
-
|
|
7
|
+
// src/cli/commands/agent.ts
|
|
8
8
|
const STATE_FILE_NAME = "agent-state.json";
|
|
9
9
|
function stateFilePath(runtime) {
|
|
10
10
|
return path.join(runtime.context.config.dataDir, STATE_FILE_NAME);
|
|
@@ -20,8 +20,8 @@ function loadState(runtime) {
|
|
|
20
20
|
}
|
|
21
21
|
function saveState(runtime, state) {
|
|
22
22
|
const dir = path.dirname(stateFilePath(runtime));
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
ensurePrivateDir(dir);
|
|
24
|
+
writePrivateFileSync(stateFilePath(runtime), JSON.stringify(state, null, 2));
|
|
25
25
|
}
|
|
26
26
|
function requireSessionId(runtime) {
|
|
27
27
|
const state = loadState(runtime);
|
|
@@ -63,6 +63,12 @@ async function agentStop(runtime) {
|
|
|
63
63
|
sessionId
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
+
/** Only connection-level failures justify a restart + re-run. */
|
|
67
|
+
function isRetryableFailure(message) {
|
|
68
|
+
if (isConnectionError(message)) return true;
|
|
69
|
+
const lower = message.toLowerCase();
|
|
70
|
+
return lower.includes("session") && (lower.includes("dead") || lower.includes("terminated"));
|
|
71
|
+
}
|
|
66
72
|
async function executeAgentCommand(runtime, input) {
|
|
67
73
|
const sessionId = requireSessionId(runtime);
|
|
68
74
|
await ensureReady(runtime, sessionId);
|
|
@@ -71,16 +77,24 @@ async function executeAgentCommand(runtime, input) {
|
|
|
71
77
|
type: input.type,
|
|
72
78
|
payload: input.payload
|
|
73
79
|
});
|
|
74
|
-
|
|
75
|
-
const first = await attempt();
|
|
76
|
-
if (first.resultStatus === "failed") throw new Error(first.resultMessage ?? "Command failed");
|
|
77
|
-
return first;
|
|
78
|
-
} catch {
|
|
80
|
+
const retryAfterRestart = async () => {
|
|
79
81
|
await runtime.api.restartSession(sessionId);
|
|
80
82
|
const second = await attempt();
|
|
81
83
|
if (second.resultStatus === "failed") throw new Error(second.resultMessage ?? "Command failed after retry");
|
|
82
84
|
return second;
|
|
85
|
+
};
|
|
86
|
+
const noRetry = input.type === "restart" || input.type === "terminate";
|
|
87
|
+
let first;
|
|
88
|
+
try {
|
|
89
|
+
first = await attempt();
|
|
90
|
+
} catch (error) {
|
|
91
|
+
if (noRetry || !isRetryableFailure(error.message)) throw error;
|
|
92
|
+
return await retryAfterRestart();
|
|
83
93
|
}
|
|
94
|
+
if (first.resultStatus !== "failed") return first;
|
|
95
|
+
const message = first.resultMessage ?? "Command failed";
|
|
96
|
+
if (noRetry || !isRetryableFailure(message)) throw new Error(message);
|
|
97
|
+
return await retryAfterRestart();
|
|
84
98
|
}
|
|
85
99
|
async function agentNavigate(runtime, input) {
|
|
86
100
|
const result = await executeAgentCommand(runtime, {
|
|
@@ -184,16 +198,14 @@ async function agentCleanup(runtime, input) {
|
|
|
184
198
|
...runtime.api.cleanupSessions(input)
|
|
185
199
|
};
|
|
186
200
|
}
|
|
187
|
-
|
|
188
|
-
//#region src/cli/output/result-formatter.ts
|
|
201
|
+
// src/cli/output/result-formatter.ts
|
|
189
202
|
function formatResult(resultStatus, message) {
|
|
190
203
|
return {
|
|
191
204
|
resultStatus,
|
|
192
205
|
message
|
|
193
206
|
};
|
|
194
207
|
}
|
|
195
|
-
|
|
196
|
-
//#region src/cli/commands/session-start.ts
|
|
208
|
+
// src/cli/commands/session-start.ts
|
|
197
209
|
async function runSessionStart(runtime, input) {
|
|
198
210
|
const session = await runtime.api.createSession(input);
|
|
199
211
|
return {
|
|
@@ -201,29 +213,24 @@ async function runSessionStart(runtime, input) {
|
|
|
201
213
|
sessionId: session.sessionId
|
|
202
214
|
};
|
|
203
215
|
}
|
|
204
|
-
|
|
205
|
-
//#region src/cli/commands/session-status.ts
|
|
216
|
+
// src/cli/commands/session-status.ts
|
|
206
217
|
async function runSessionStatus(runtime, input) {
|
|
207
218
|
return runtime.api.getSession(input.sessionId);
|
|
208
219
|
}
|
|
209
|
-
|
|
210
|
-
//#region src/cli/commands/session-stop.ts
|
|
220
|
+
// src/cli/commands/session-stop.ts
|
|
211
221
|
async function runSessionStop(runtime, input) {
|
|
212
222
|
await runtime.api.terminateSession(input.sessionId);
|
|
213
223
|
return { terminated: true };
|
|
214
224
|
}
|
|
215
|
-
|
|
216
|
-
//#region src/cli/commands/session-cleanup.ts
|
|
225
|
+
// src/cli/commands/session-cleanup.ts
|
|
217
226
|
async function runSessionCleanup(runtime, input) {
|
|
218
227
|
return runtime.api.cleanupSessions(input);
|
|
219
228
|
}
|
|
220
|
-
|
|
221
|
-
//#region src/cli/commands/session-restart.ts
|
|
229
|
+
// src/cli/commands/session-restart.ts
|
|
222
230
|
async function runSessionRestart(runtime, input) {
|
|
223
231
|
return await runtime.api.restartSession(input.sessionId);
|
|
224
232
|
}
|
|
225
|
-
|
|
226
|
-
//#region src/cli/commands/session-auth.ts
|
|
233
|
+
// src/cli/commands/session-auth.ts
|
|
227
234
|
async function runSessionAuth(runtime, input) {
|
|
228
235
|
const token = runtime.api.rotateSessionToken(input.sessionId);
|
|
229
236
|
return {
|
|
@@ -231,8 +238,7 @@ async function runSessionAuth(runtime, input) {
|
|
|
231
238
|
valid: runtime.context.tokenService.validate(input.sessionId, token)
|
|
232
239
|
};
|
|
233
240
|
}
|
|
234
|
-
|
|
235
|
-
//#region src/cli/commands/command-run.ts
|
|
241
|
+
// src/cli/commands/command-run.ts
|
|
236
242
|
async function runCommand(runtime, input) {
|
|
237
243
|
if (!input.sessionId) throw new Error("No active session. Start or restart a session first.");
|
|
238
244
|
try {
|
|
@@ -245,8 +251,7 @@ async function runCommand(runtime, input) {
|
|
|
245
251
|
throw new Error(`Command rejected: ${error.message}`, { cause: error });
|
|
246
252
|
}
|
|
247
253
|
}
|
|
248
|
-
|
|
249
|
-
//#region src/cli/commands/page-content.ts
|
|
254
|
+
// src/cli/commands/page-content.ts
|
|
250
255
|
async function runPageContent(runtime, input) {
|
|
251
256
|
return await runtime.api.getContent(input.sessionId, {
|
|
252
257
|
mode: input.mode,
|
|
@@ -254,31 +259,26 @@ async function runPageContent(runtime, input) {
|
|
|
254
259
|
maxChars: input.maxChars
|
|
255
260
|
});
|
|
256
261
|
}
|
|
257
|
-
|
|
258
|
-
//#region src/cli/commands/memory-search.ts
|
|
262
|
+
// src/cli/commands/memory-search.ts
|
|
259
263
|
async function runMemorySearch(runtime, input) {
|
|
260
264
|
if (!input.taskIntent || !input.taskIntent.trim()) throw new Error("taskIntent is required");
|
|
261
265
|
return runtime.api.searchMemory(input);
|
|
262
266
|
}
|
|
263
|
-
|
|
264
|
-
//#region src/cli/commands/memory-inspect.ts
|
|
267
|
+
// src/cli/commands/memory-inspect.ts
|
|
265
268
|
async function runMemoryInspect(runtime, input) {
|
|
266
269
|
if (!input.insightId || !input.insightId.trim()) throw new Error("insightId is required");
|
|
267
270
|
return runtime.api.inspectMemory(input.insightId);
|
|
268
271
|
}
|
|
269
|
-
|
|
270
|
-
//#region src/cli/commands/memory-verify.ts
|
|
272
|
+
// src/cli/commands/memory-verify.ts
|
|
271
273
|
async function runMemoryVerify(runtime, input) {
|
|
272
274
|
if (!input.insightId || !input.insightId.trim()) throw new Error("insightId is required");
|
|
273
275
|
return runtime.api.verifyMemory(input.insightId);
|
|
274
276
|
}
|
|
275
|
-
|
|
276
|
-
//#region src/cli/commands/memory-stats.ts
|
|
277
|
+
// src/cli/commands/memory-stats.ts
|
|
277
278
|
async function runMemoryStats(runtime) {
|
|
278
279
|
return runtime.api.memoryStats();
|
|
279
280
|
}
|
|
280
|
-
|
|
281
|
-
//#region src/cli/index.ts
|
|
281
|
+
// src/cli/index.ts
|
|
282
282
|
const collect = (value, previous = []) => [...previous, value];
|
|
283
283
|
async function main() {
|
|
284
284
|
const runtime = createCliRuntime();
|
|
@@ -513,7 +513,7 @@ async function main() {
|
|
|
513
513
|
await startMcpServer();
|
|
514
514
|
});
|
|
515
515
|
program.command("setup").description("Configure agentic-browser as MCP server for your AI tool").action(async () => {
|
|
516
|
-
const { runSetup } = await import("../setup-
|
|
516
|
+
const { runSetup } = await import("../setup-DwFaZOPf.mjs");
|
|
517
517
|
await runSetup();
|
|
518
518
|
});
|
|
519
519
|
await program.parseAsync(process.argv);
|
|
@@ -526,5 +526,4 @@ main().then((keepAlive) => {
|
|
|
526
526
|
console.error(JSON.stringify({ error: message }));
|
|
527
527
|
process.exit(1);
|
|
528
528
|
});
|
|
529
|
-
//#endregion
|
|
530
529
|
export {};
|