Skip to content

feat: add browser automation tool and default file tool path - #1530

Merged
avoidwork merged 13 commits into
mainfrom
feat/browser-automation-tool
Oct 25, 2026
Merged

avoidwork merged 13 commits into
mainfrom
feat/browser-automation-tool

Conversation

@avoidwork

@avoidwork avoidwork commented Oct 25, 2026 •

Copy link
Copy Markdown
Owner

Description

Adds a browser automation tool that drives a real headless Chromium browser via puppeteer-core, supporting navigate, click, type/fill, press, screenshot, extract, waitFor, and evaluate actions. Every outbound URL is validated against filterUrl (SSRF protection). This closes the gap between madz's read-only web toolset and actually acting on a web page, and replaces the deprecated extractWeb/renderWeb/screenshotWeb tools.

Also makes the file tool's path argument optional, defaulting it to the active project cwd (falling back to config.cwd) and resolving relative paths against that base — mirroring the @ file picker. Adds a module-level active-project store (src/workspace/project.js) that the TUI writes to on select/clear and the file tool reads at call time. Normalizes the sandbox allowlist so relative "./" entries are replaced with the absolute config.cwd.

Type of Change

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactor (no functional changes)
  • Performance improvement
  • CI / build / tooling

Testing

  • Unit tests: tests/unit/tools/browser.test.js — Zod schema validation for all actions and inputs, URL rejection via filterUrl, session reuse/close.
  • Unit tests: tests/unit/tools/file.test.js — default-path and relative-path resolution against the active project cwd.
  • Unit tests: tests/unit/workspace/project.test.js — active-project store get/set/clear.
  • Unit tests: tests/unit/config_loader.test.js — sandbox path normalization.
  • Edge cases: invalid URL, selector not found, timeout, invalid action, omitted path.
  • Note: the browser integration test (task 3.2) is not yet written; it remains unchecked in openspec/changes/browser-automation-tool/tasks.md.

Coverage

  • Line coverage maintained (90.47% → 90.53%)

Checklist

  • npm run lint passes
  • Tests pass with maintained line coverage
  • No forbidden patterns used
  • Conventional Commit style applied

Closes #1517

OpenSpec change for a browser-automation tool that drives a headless
Chromium browser via puppeteer-core, supporting navigate, click, type/fill,
press, screenshot, extract, waitFor, and evaluate actions with URL
validation against the sandbox allowlist.
@avoidwork avoidwork self-assigned this Oct 25, 2026
Add a browser tool that drives a real headless Chromium via puppeteer-core:
navigate, click, type, fill, press, screenshot, extract, waitFor, evaluate,
and close. Supports persistent sessions via sessionId for chaining actions
across calls. Validates outbound URLs against the sandbox allowlist (SSRF
protection). Includes unit tests for the Zod schema and action dispatch.
Replace new Function() wrapping with a direct string expression passed to
page.evaluate. Puppeteer evaluates string arguments as Runtime.evaluate
expressions, so no function-body wrapping is needed. Removes the AGENTS.md
forbidden-pattern violation (new Function) and updates the schema description
and tests to use expression strings.
networkidle0/networkidle2 block on pages with persistent connections
(ads, trackers, streaming) and false-timeout. The load event fires when
the page's resources are done loading without waiting for network idle.
The browser tool's screenshot action now captures a JPEG via puppeteer,
writes it to memory/screenshots/, and returns { ok, mimeType: "image/jpeg",
path } so the agent can feed the path to readImage for vision analysis.
This is a 1:1 match with the removed screenshotWeb tool. The screenshots
directory is injectable via options for tests.
Make the file tool's path argument optional, defaulting it to the active
project cwd (falling back to config.cwd) and resolving relative paths
against that base — mirroring the @ file picker. Adds a module-level
active-project store that the TUI writes to on select/clear and the file
tool reads at call time.
@avoidwork avoidwork changed the title feat: add browser automation tool feat: add browser automation tool and default file tool path Oct 25, 2026
Every browser call now persists its session and returns the sessionId in
the response, so callers can chain actions (navigate -> extract -> close)
without supplying a sessionId up front. Unused sessions are reclaimed by
the existing 5-minute idle GC.

Also align the file tool's glob action with search/grep by reading the
shared `pattern` parameter instead of a separate `glob` key.
The sandbox allowlist contained a relative "./" entry, which resolves
against process.cwd() and drifts when the process changes directory.
This caused scanAgents and other path-validating tools to reject paths
that were actually inside the project.

Normalize sandbox.paths in _setResolvedConfig: drop relative "."/"./"
entries and append the absolute config.cwd, so every consumer (path
validation, tool allowlists, subagent scopes) sees the project root
explicitly regardless of the process working directory.
@avoidwork
avoidwork merged commit db2367a into main Oct 25, 2026
2 checks passed
@avoidwork
avoidwork deleted the feat/browser-automation-tool branch October 25, 2026 19:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add browser automation tool

1 participant