Commit Graph

40 Commits

Author SHA1 Message Date
Adrià Arrufat
7e778a17d6 MCP/CDP: unify node registration
This fixes a bug in MCP where interactive elements were not assigned
a backendNodeId, preventing agents from clicking or filling them. Also
extracts link collection to a shared browser module.
2026-03-26 23:51:43 +09:00
Karl Seguin
cf641ed458 Merge pull request #1990 from lightpanda-io/remove_cdp_generic
Remove cdp generic
2026-03-26 07:49:13 +08:00
Karl Seguin
0dd0495ab8 Removes CDPT (generic CDP)
CDPT used to be a generic so that we could inject Browser, Session, Page and
Client. At some point, it [thankfully] became a generic only to inject Client.

This commit removes the generic and bakes the *Server.Client instance in CDP.
It uses a socketpair for testing.

BrowserContext is still generic, but that's generic for a very different reason
and, while I'd like to remove that generic too, it belongs in a different PR.
2026-03-25 17:43:30 +08:00
Adrià Arrufat
8e315e551a forms: extract form node registration logic 2026-03-25 09:30:06 +09:00
Adrià Arrufat
260768463b Merge branch 'main' into osc/feat-mcp-detect-forms 2026-03-24 09:25:47 +09:00
Adrià Arrufat
c3a2318eca fix: pass allocator as first parameter in forms.zig 2026-03-23 15:27:49 +09:00
Adrià Arrufat
4f1b499d0f zig fmt 2026-03-23 13:52:28 +09:00
Karl Seguin
c9bc370d6a Extract Session.wait into a Runner
This is done for a couple reasons. The first is just to have things a little
more self-contained for eventually supporting more advanced "wait" logic, e.g.
waiting for a selector.

The other is to provide callers with more fine-grained controlled. Specifically
the ability to manually "tick", so that they can [presumably] do something
after every tick. This is needed by the test runner to support more advanced
cases (cases that need to test beyond 'load') and it also improves (and fixes
potential use-after-free, the lp.waitForSelector)
2026-03-23 12:30:41 +08:00
Adrià Arrufat
4b29823a5b refactor: simplify form extraction and remove const casts 2026-03-23 13:24:21 +09:00
Adrià Arrufat
a6d2ec7610 refactor: share form node ID serialization between MCP and CDP 2026-03-23 10:18:24 +09:00
Matt Van Horn
78c6def2b1 mcp: add detectForms tool for structured form discovery
Add a detectForms MCP tool and lp.detectForms CDP command that return
structured form metadata from the current page. Each form includes its
action URL, HTTP method, and fields with names, types, required status,
values, select options, and backendNodeIds for use with the fill tool.

This lets AI agents discover and fill forms in a single step instead of
calling interactiveElements, filtering for form fields, and guessing
which fields belong to which form.

New files:
- src/browser/forms.zig: FormInfo/FormField structs, collectForms()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 08:40:50 -07:00
Adrià Arrufat
e10ccd846d CDP: add waitForSelector to lp.actions
It refactors the implementation from MCP to be reused.
2026-03-22 00:09:02 +09:00
Karl Seguin
a5378feb1d Merge pull request #1927 from lightpanda-io/feat/fetch-wait-options
Feat/fetch wait options
2026-03-21 07:18:59 +08:00
Karl Seguin
a4cb5031d1 Tweak wait_until option
Small tweaks to https://github.com/lightpanda-io/browser/pull/1896

Improve the wait ergonomics with an Option with default parameter. Revert
page pointer logic to original (don't think that change was necessary).
2026-03-19 20:29:20 +08:00
Adrià Arrufat
9c2393351d SemanticTree: simplify max_depth logic 2026-03-19 20:25:20 +09:00
Adrià Arrufat
7a7c4b9f49 SemanticTree): add backendNodeId and maxDepth support 2026-03-19 10:18:08 +09:00
shaewe180
09327c3897 feat: fetch add wait_until parameter for page loads options
Add `--wait_until` and `--wait_ms` CLI arguments to configure session wait behavior. Updates `Session.wait` to evaluate specific page load states (`load`, `domcontentloaded`, `networkidle`, `fixed`) before completing the wait loop.
2026-03-18 15:08:51 +08:00
Adrià Arrufat
e1b14a6833 SemanticTree: enable prune by default 2026-03-18 11:25:38 +09:00
Adrià Arrufat
015edc3848 SemanticTree: implement interactiveOnly filter and optimize token usage 2026-03-18 10:56:56 +09:00
Adrià Arrufat
f508d37426 lp: validate params in node actions and rename variables 2026-03-16 23:50:15 +09:00
Adrià Arrufat
a74e46debf actions: make scroll coordinates optional
Updates the scroll action to accept optional x and y coordinates. This
allows scrolling on a single axis without resetting the other to zero.
2026-03-16 22:44:37 +09:00
Adrià Arrufat
21e9967a8a actions: simplify function names 2026-03-16 16:31:33 +09:00
Adrià Arrufat
32f450f803 browser: centralize node interaction logic
Extracts click, fill, and scroll logic from CDP and MCP domains into a
new dedicated actions module to reduce code duplication.
2026-03-16 14:22:15 +09:00
Adrià Arrufat
1972142703 mcp: add tests for click, fill, and scroll actions 2026-03-16 14:16:20 +09:00
Adrià Arrufat
b10d866e4b Add click, fill, and scroll interaction tools
Adds click, fill, and scroll functionality to both CDP and MCP
to support programmatic browser interactions.
2026-03-16 13:55:37 +09:00
Adrià Arrufat
af803da5c8 cdp.lp: use enum for getSemanticTree format param
Leverages std.json.parse to automatically validate the format param into a type-safe enum.
2026-03-11 16:21:43 +09:00
Adrià Arrufat
d1ee0442ea Merge branch 'main' into semantic-tree 2026-03-10 21:48:49 +09:00
Adrià Arrufat
56f47ee574 Merge branch 'main' into semantic-tree 2026-03-10 17:26:34 +09:00
egrs
74f0436ac7 merge main, resolve conflicts with getInteractiveElements 2026-03-10 09:25:12 +01:00
egrs
22d31b1527 add LP.getStructuredData CDP command 2026-03-10 09:19:51 +01:00
egrs
dc3958356d address review feedback
- TreeWalker.Full instead of FullExcludeSelf so querying a specific
  nodeId evaluates the root element itself
- resolve href to absolute URL via URL.resolve
- isDisabled checks ancestor <fieldset disabled> with legend exemption
- parameter order: allocator before *Page per convention
2026-03-10 08:13:01 +01:00
egrs
a417c73bf7 add LP.getInteractiveElements CDP command
Returns a structured list of all interactive elements on a page:
buttons, links, inputs, ARIA widgets, contenteditable regions, and
elements with event listeners. Includes accessible names, roles,
listener types, and key attributes.

Event listener introspection (both addEventListener and inline
handlers) is unique to LP — no other browser exposes this to
automation code.
2026-03-09 19:46:12 +01:00
Adrià Arrufat
b8a3135835 SemanticTree: add pruning support and move logic to walk 2026-03-09 13:02:03 +09:00
Adrià Arrufat
b674c2e448 CDP/MCP: add highly compressed text format for semantic tree 2026-03-08 22:42:00 +09:00
Adrià Arrufat
248851701f Refactor: move SemanticTree to core and expose via MCP tools 2026-03-06 15:44:03 +09:00
Adrià Arrufat
0f46277b1f CDP: implement LP.getSemanticTree for native semantic DOM extraction 2026-03-06 15:29:32 +09:00
Adrià Arrufat
b2e301418f cdp.lp: use page.document instead of window._document 2026-03-03 17:11:16 +09:00
Adrià Arrufat
334a2e44a1 lp: simplify dom_node resolution in getMarkdown 2026-03-03 17:08:43 +09:00
Adrià Arrufat
c9121a03d2 cdp: move LP.getMarkdown test to lp domain 2026-03-03 16:39:31 +09:00
Adrià Arrufat
cc93180d57 cdp: add LP domain and getMarkdown method
This PR introduces a custom CDP domain 'LP' (Lightpanda) to expose browser-specific tools. The first method, 'LP.getMarkdown', allows retrieving a Markdown representation of the DOM or a specific node by its 'nodeId'. This is optimized for AI agents and LLM-based scraping tasks.
2026-03-03 16:35:48 +09:00