Commit Graph
8933 Commits
Author SHA1 Message Date
Adrià Arrufat 0865f4e337 agent: fold the browser quartet onto lp.ToolSession
Agent held the same Browser/Session/Notification/registry fields and
teardown order as mcp/Server.zig, plus its own "enableConsoleCapture
after every newSession" for /reset. ToolSession.restartSession() owns
that now; init is written in terms of it.

Claude-Session: https://claude.ai/code/session_01M6WGk8wZSE28efFQkYT9SK
2026-08-27 16:40:53 +02:00
Adrià Arrufat dadbae121c ToolSession: test the shared-thread contract
Two sessions on one thread, each entered only around its own use, with
JS state proving the isolates are separate and a balanced park/enter/
deinit teardown. Pins what the C API relies on without Server in the loop.

Claude-Session: https://claude.ai/code/session_01M6WGk8wZSE28efFQkYT9SK
2026-08-27 16:35:11 +02:00
Adrià Arrufat d8893f95d7 mcp: bracket every isolate use, drop park_isolates
stdio kept the isolate permanently entered while HTTP parked it between
requests, so a handler touching page JS without enterIsolate passed the
stdio-mode tests and only failed under --port. Bracket unconditionally:
stdio is the one-isolate case of the same discipline.

The flag survives only as `multi_session`, which is what it always gated:
the session tools need a transport that routes by id.

Claude-Session: https://claude.ai/code/session_01M6WGk8wZSE28efFQkYT9SK
2026-08-27 16:30:49 +02:00
Adrià Arrufat 071eca1f3f mcp: fold Server.Session onto lp.ToolSession
Extract the Browser+Session+Notification+node Registry quartet, with its
ordering-sensitive init/teardown and isolate enter/exit, into
src/ToolSession.zig. mcp/Server.zig's sessions map now holds
*lp.ToolSession directly; the session id lives only as the map key.

Claude-Session: https://claude.ai/code/session_01M6WGk8wZSE28efFQkYT9SK
2026-08-27 16:27:27 +02:00
Karl Seguin 931da06026 Merge pull request #3300 from lightpanda-io/increase-ci-timeout
CI: bump timeout from 20 to 30 for e2e-test
2026-08-27 17:10:26 +08:00
Karl Seguin 60b2848908 Merge pull request #3303 from lightpanda-io/fix-wpt-build
fix the wpt build
2026-08-27 15:55:06 +08:00
Karl Seguin 1b59bc8d3b fix the wpt build 2026-08-27 15:23:45 +08:00
Karl Seguin 98ff4b9b4d CI: bump timeout from 20 to 30 for e2e-test
Mimic's https://github.com/lightpanda-io/browser/pull/3294

I looked into this a little bit, and the main issue is that we build the binary
in releasefast twice: once for the snapshot and once for the browser itself.
Each build takes ~10 minutes.

The snapshot cache almost always misses (since any change to webapi/*
invalidates it). I don't see a great solution.
2026-08-27 13:54:30 +08:00
Karl Seguin a7bda0ea57 Merge pull request #3284 from lightpanda-io/xhr-blob
XHR Blob Response Type
2026-08-27 10:44:05 +08:00
Karl Seguin abf5bdecb6 mem: Use new clearResponse() to eagerly free XHR JSON response
And, add blob tests
2026-08-27 09:42:02 +08:00
Muki Kiboigo 3d42ffa0f8 properly ref count blob in XHR response 2026-08-27 09:20:34 +08:00
Muki Kiboigo adb4551362 support Blob as XHR responseType 2026-08-27 09:20:34 +08:00
Karl Seguin b5656eed82 Merge pull request #3292 from lightpanda-io/fetch-markdown-opts
fetch: add --selector and --max-bytes, honor --strip-mode for markdown
2026-08-27 08:28:20 +08:00
muki 57b86112b3 Merge pull request #3240 from lightpanda-io/xhr-async-flag
XHR Sync Request
2026-08-26 17:11:48 -07:00
Karl Seguin 05627c5368 handle error in json+png error
improve log error message when 1 of multiple URLs fails to fetch
2026-08-27 08:11:15 +08:00
Karl Seguin 23d18ab3aa Merge pull request #3296 from lightpanda-io/silence-write-failed-test-http-error
chore: silence test log
2026-08-27 07:43:41 +08:00
Karl Seguin b5c25db3fc chore: silence test log 2026-08-27 07:42:23 +08:00
Karl Seguin 6955751c10 Merge pull request #3285 from lightpanda-io/mem-vmhwm
mem: include v8 functions in binary layout optimization
2026-08-27 07:35:30 +08:00
Karl Seguin fce38a1aa8 Merge pull request #3289 from lightpanda-io/fix-double-releases
fix: Fix double-release and other (edge-case) memory issues
2026-08-27 07:34:45 +08:00
Karl Seguin 00a2a78303 Merge pull request #3288 from lightpanda-io/WorkerNavigator
WebAPI: Add WorkerNavigator
2026-08-27 07:34:31 +08:00
Karl Seguin c70557ad08 Merge pull request #3287 from lightpanda-io/wpt-mouse-boundary-events
webapi: improve hover events
2026-08-27 07:32:34 +08:00
Karl Seguin e0f6eb5e04 Merge pull request #3286 from lightpanda-io/usp-iterable-init
webapi: URLSerachParams @@iterator init
2026-08-27 07:32:03 +08:00
Muki Kiboigo bcd77bf462 set ready state to done on sync XHR error 2026-08-26 08:05:53 -07:00
Muki Kiboigo b20bb1f553 get rid of extra releaseSelfRef 2026-08-26 08:05:23 -07:00
Pierre Tachoire 70d50b1f22 Merge pull request #3294 from lightpanda-io/ci-release-timeout
ci: increase release build timeout 20 -> 30
2026-08-26 16:01:43 +02:00
Adrià Arrufat f1ae05f6e7 Merge pull request #3291 from lightpanda-io/links-quality
links: dedup by href, skip hidden, fall back to alt/aria-label/title
2026-08-26 15:54:26 +02:00
Adrià Arrufat 33b8bdbb4c fetch: --dump-selector without --dump is an error, like --dump-max-bytes 2026-08-26 15:45:24 +02:00
Adrià Arrufat 56241e26b8 dump: take max_bytes in Opts
Review feedback: markdown caps its own output through Opts.max_bytes while
the html dump left it to each caller, so the html tool and fetch each
carried a copy of the LimitedWriter wrapping. root and deep now do it,
with a no-cap fast path so innerHTML/outerHTML are unaffected.
2026-08-26 15:44:48 +02:00
Adrià Arrufat 6811cc8226 fetch: per-page errors, an "error" field in --json, --fail-on-http-error
A wait failure on one URL aborted the whole multi-URL fetch with no
output, the wait_ms budget was computed once before the loop so N pages
could take N times the budget, navigation failures exited 0 with an empty
dump, and HTTP 4xx/5xx were indistinguishable from success by exit code.

Each page now has its own error slot: wait, navigation and dump failures
are recorded there instead of returned, every page is still written (the
JSON envelope carries the name under "error"), then the first failure is
returned so the process exits 1. The remaining budget is recomputed per
page. --fail-on-http-error turns a status >= 400 into exit 22, curl's
code for the same condition; the dump is written first either way.
2026-08-26 15:35:15 +02:00
Adrià Arrufat 1fb7a1b983 fetch: namespace the dump options in Config too 2026-08-26 15:34:15 +02:00
Adrià Arrufat e46964e261 markdown: reuse dump's shouldStripElement 2026-08-26 15:32:25 +02:00
Pierre Tachoire f1fcdb6617 ci: increase release build timeout 20 -> 30 2026-08-26 15:32:21 +02:00
Adrià ArrufatandKarl Seguin c78c1d3823 fetch: namespace dump flags
Co-authored-by: Karl Seguin <karlseguin@users.noreply.github.com>
2026-08-26 15:28:18 +02:00
Adrià Arrufat 5870ce1120 refactor(links): use accessible name from AXNode for link text 2026-08-26 15:16:56 +02:00
Adrià Arrufat d3bad960c3 fetch: add --selector and --max-bytes, honor --strip-mode for markdown
--strip-mode was silently ignored for --dump markdown, and fetch had no
way to scope a dump to one element or cap its size although the markdown
and html tools have both.

--selector dumps the first matching element in any dump mode, --max-bytes
caps html and markdown with the tools' truncation marker, and markdown
now honors strip ui (images; scripts, styles and hidden elements are
never rendered, so the other groups don't apply).
2026-08-26 13:23:18 +02:00
Adrià Arrufat fbb9f8c8fa links: fix test expectation, the test frame has no base URL 2026-08-26 13:14:30 +02:00
Adrià Arrufat 6dca2c8917 links: dedup by href, skip hidden, fall back to alt/aria-label/title
The links tool returned every a[href] verbatim: hidden nav entries,
one row per duplicate href, and null text for image and icon links even
though markdown already knows to use alt. Nav-heavy pages produced
thousands of rows for an agent looking for one link.

One entry per resolved href (the first, upgraded with text from a later
duplicate), hidden anchors skipped with the same check tree uses, text
falling back to aria-label, title, then a descendant img alt. The tool
gains an optional limit.
2026-08-26 13:13:08 +02:00
Karl Seguin cfd921ecab fix: Fix double-release and other (edge-case) memory issues
Our `Arena` from the `ArenaPool` now tracks if it's already been released. On
a subsequent release, it panics then and there. Without this, the code will
almost certainly panic anyways, but it will panic in a seemingly unrelated
place. Hopefully this makes identifying future cases of this easier (since we'll
get the stack trace of the re-releaser).

Fix 3 separate memory issues, all edge cases.

1 - an XHR error handler that re-open/sends would incorrectly null the new
    transfer (maybe this isn't that odd, maybe it's a common retry-on-error).

2 - On a curl_easy_pause error (from WebSocket.zig) we now unqueue the just-
    queued message, because the error will errdefer the message arena to be
    cleaned up.

3 - ScriptManager now cleans up after itself on a failure prior to submit()
    being called.
2026-08-26 18:24:12 +08:00
Karl Seguin f5c458047e WebAPI: Add WorkerNavigator
A worker gets a distinct Navigator type (WorkerNavigator) which only exposes
a subset of what Navigator does.

Previously, we achieved this by exposing Navigator but with a bunch of accessors
 / functions with .{.exposed = .window}. That worked fine, except the type name
was still "Navigator". This introduces an actual WorkerNavigator.
2026-08-26 16:34:26 +08:00
Pierre Tachoire 2013249a2a Merge pull request #3267 from lightpanda-io/strip-auth-cross-origin-redirect
http: strip Authorization on cross-origin redirects
2026-08-26 10:16:52 +02:00
Pierre Tachoire 467167d6e6 http: strip Authorization on cross-origin redirects 2026-08-26 10:00:11 +02:00
Adrià Arrufat 5f8eb43867 Merge pull request #3276 from lightpanda-io/mcp-tool-annotations
mcp: add title and annotations to tools/list
2026-08-26 09:46:48 +02:00
Pierre Tachoire f2169836e5 Merge pull request #3256 from lightpanda-io/mcp-origin
mcp: enforce HTTP conditions
2026-08-26 09:42:29 +02:00
Karl Seguin 7ff12215b7 webapi: improve hover events
The Page now tracks the element currently being hovered. We need to track this
so that subsequent mouse events can fire the correct events. This is largely a
WebDriver (WPT) change, but it's also triggered from CDP's
`input.dispatchMouseEvent`.

So, for example, if CDP `dispatchMouseEvent` with a mouseMoved to element1
we'll fire a mouseenter. If the same command is issue for the same element, we
should NOT trigger a mouseout and mouseenter.
2026-08-26 15:31:24 +08:00
Karl Seguin f65ff762b8 webapi: URLSerachParams @@iterator init
This has been on my TODO for a long time. https://github.com/lightpanda-io/browser/pull/3238
added support for the @@iterator protocol and now URLSearchParams' init can
use it.

We used to only support a v8::Array, but now any type that implements the
@@iterator protocol can be passed into URLSearchParams.

This also fixes and simplifies the js.Object iterator. It now yields name +
value (so callers don't need to get the name then lookup the value). But it
isn't just about making it easier to use. The name can be a lossy UTF-8
conversion, so the value lookup can fail. By internalizing the value lookup we
can use the v8::String directly for the lookup.

Fixes a handful of WPT /url/ cases
2026-08-26 14:57:02 +08:00
Adrià Arrufat 48551d241a mcp: navigation and waits are not read-only; consoleLogs is not idempotent
Review feedback: navigation writes cookies and storage and a wait lets page
scripts mutate state, so neither can be auto-approved as read-only.
consoleLogs drains its buffer, so repeated calls differ.
2026-08-26 08:44:57 +02:00
Adrià Arrufat 8f2d1de266 Merge pull request #3279 from lightpanda-io/interactive-visibility
interactive: skip hidden elements
2026-08-26 08:42:56 +02:00
Karl Seguin 8c5b684760 Optimize visibility check
Since all children of an invisible element are skipped, the visibility cache
serves no purpose AND we can assume that any element we do visit has a visible
parent and thus just need to check the element's own visibility.
2026-08-26 14:14:03 +08:00
Adrià Arrufat b814af122d interactive: skip hidden elements
interactiveElements and findElement returned elements under display:none
or [hidden], so agents were offered controls no user could reach and the
list disagreed with tree, which already filters on visibility. Reuse the
same cached check and skip the hidden subtree.
2026-08-26 14:02:56 +08:00
Karl Seguin 2fbfbea955 Merge pull request #3269 from lightpanda-io/markdown-hidden-content
markdown: skip hidden elements
2026-08-26 13:54:49 +08:00