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 CHANGED
@@ -3,14 +3,14 @@
3
3
  ## Quick Reference
4
4
 
5
5
  ```bash
6
- npm run build # tsdown (~20ms)
7
- npm run typecheck # tsc --noEmit
8
- npm run lint # oxlint
9
- npm run lint:fix # oxlint --fix
10
- npm run format # oxfmt --write
11
- npm test # vitest run
12
- npm run test:watch # vitest
13
- npm run docs:dev # vocs dev server
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, 7 tools wrapping AgenticBrowserCore)
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 v14**: colon-namespaced commands (`session:start`, `memory:search`)
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 | Purpose |
121
- | ----------------------- | --------------------------------------------------------------------------------------------------------- |
122
- | `browser_start_session` | Start Chrome, return sessionId |
123
- | `browser_navigate` | Navigate to URL |
124
- | `browser_interact` | click / type / press / waitFor / scroll / hover / select / toggle / goBack / goForward / refresh / dialog |
125
- | `browser_get_content` | Get page title / text / html |
126
- | `browser_get_elements` | Discover interactive elements |
127
- | `browser_search_memory` | Search task memory |
128
- | `browser_stop_session` | Stop Chrome 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
@@ -13,7 +13,7 @@ CLI and MCP server to control a local Chrome session for AI agents.
13
13
 
14
14
  ## Requirements
15
15
 
16
- - Node.js 20+
16
+ - Node.js 22+
17
17
  - Installed Chrome
18
18
 
19
19
  ## Install
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { r as createCliRuntime } from "../runtime-BzdbtFF4.mjs";
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
- //#region src/cli/commands/agent.ts
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
- fs.mkdirSync(dir, { recursive: true });
24
- fs.writeFileSync(stateFilePath(runtime), JSON.stringify(state, null, 2));
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
- try {
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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-DUAjdbQ3.mjs");
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 {};