Commit Graph
8600 Commits
Author SHA1 Message Date
Karl Seguin 0f6ea46b2e mem: Swith EventTarget's _type to a bare tag
Same change as https://github.com/lightpanda-io/browser/pull/3128 but for
EventTarget. This shrinks all EventTargets (i.e. most WebAPI interfaces) by 8
bytes.
2026-08-12 08:01:12 +08:00
Karl Seguin efc7613768 Merge pull request #3172 from lightpanda-io/js_mem_gauge
metrics: Add js memory gauge
2026-08-12 07:46:21 +08:00
Karl Seguin 99bfc2fdeb Merge pull request #3167 from lightpanda-io/self-hosted
dev: add -Ddev_fast flag
2026-08-11 20:47:43 +08:00
Karl Seguin fff4b4b44d Merge pull request #3171 from lightpanda-io/nikneym/webkit-matches-selector
`Element`: alias `matches` with `webkitMatchesSelector`
2026-08-11 20:38:07 +08:00
Karl Seguin 5b3de8a400 Merge pull request #3168 from lightpanda-io/shadowroot-events
webapi: improve events from shadowroot
2026-08-11 20:34:03 +08:00
Karl Seguin 6dba13b218 metrics: Add js memory gauge
Unlike the histogram, which is only captured on page teardown, this attempts to
capture the live memory (at a few selected known points, e.g. "load").
2026-08-11 20:30:45 +08:00
Halil Durak 4d8c0f6d92 update tests 2026-08-11 14:46:48 +03:00
Halil Durak 4b70b9523a Element: alias matches with webkitMatchesSelector 2026-08-11 14:46:17 +03:00
Karl Seguin e1794b4768 webapi: improve events from shadowroot
Correctly encapsulate events that happen within a shadowroot to stop from
leaking out. This involves calculating the related_target relative to the
potential node receiving the event.

Also Event.composedPath now re-uses the same path-building logic as EventManager
(previously, the same-ish algo in both places, that were out of sync).

Some smaller changes:
- input.list getter (showed up in the shadow dom wpt tests)
- activeElement getter added to ShadowDOM
- document activeElement is ShadowDOM-aware and won't cross
2026-08-11 14:12:49 +08:00
Karl Seguin 5d2910034c update v8 dep 2026-08-11 09:54:33 +08:00
Karl Seguin 77ef54f0ac dev: add -Ddev_fast flag
Only works in Debug mode. Only works on x86_64 Linux.

sets use_llvm = false and forces glibc 2.43 (1), causes v8 to be dynamically
linked (https://github.com/lightpanda-io/zig-v8-fork/pull/197).

For me, zig build -Ddev_fast is about 6x faster (~60 seconds -> ~10 seconds)

(1) https://codeberg.org/ziglang/zig/issues/31272
2026-08-11 09:39:45 +08:00
Karl Seguin 6312d43d97 Merge pull request #3164 from lightpanda-io/report-ignore-url
mask url fields from crash report
2026-08-10 16:34:31 +08:00
Karl Seguin 859b5e4efe Merge pull request #3165 from lightpanda-io/test-tcp-nodelay
chore: speed up unit tests on linux
2026-08-10 16:34:15 +08:00
Karl Seguin 73de272755 chore: speed up unit tests on linux 2026-08-10 15:51:58 +08:00
Pierre Tachoire ec16da49e3 mask url fields from crash report 2026-08-10 09:30:55 +02:00
Karl Seguin 9eba476615 Merge pull request #3157 from lightpanda-io/http-cache-limit
Entry Limit for HTTP Cache
2026-08-10 13:14:30 +08:00
Karl Seguin 8691568f33 Merge pull request #3160 from lightpanda-io/cdp-idle-notifications
runner: advance idle notifications outside the wait-condition loop
2026-08-08 11:11:36 +08:00
Karl Seguin 94bcaf801f Merge pull request #3162 from lightpanda-io/iframe-srcdoc
webapi: add support for iframe srcdoc
2026-08-08 10:40:38 +08:00
Karl Seguin cfb2fc5e9c webapi: add support for iframe srcdoc
Came up in a handful of referrer-policy WPT tests.
2026-08-08 08:18:18 +08:00
Karl Seguin 4a157eea0f Merge pull request #3161 from lightpanda-io/referrer-policy-redirect
http: recalculate Referer header on each redirect
2026-08-08 08:15:18 +08:00
Karl Seguin 17c8df5aa5 Merge pull request #3159 from lightpanda-io/custom-element-errors
webapi: Report CustomElement errors via window.reportError
2026-08-08 08:15:06 +08:00
Karl Seguin 5c1c2a1b8b Merge pull request #3150 from lightpanda-io/cdp-post-data
cdp: add request post data
2026-08-08 08:14:52 +08:00
Muki Kiboigo 32364a26da use proper default on http_cache_entry_limit option 2026-08-07 08:01:55 -07:00
Muki Kiboigo f80aa2882c use a better query for evictOverflow 2026-08-07 08:01:54 -07:00
Karl Seguin abc6f1ef76 http: recalculate Referer header on each redirect
On a redirect, recalculate the Referer header based on the new target.

Also, allow SVG anchors to be clicked (doesn't seem related, but it came up
in referrer-policy WPT tests).
2026-08-07 16:19:41 +08:00
Adrià Arrufat bf02e41919 runner: advance idle notifications outside the wait-condition loop
checkIdleNotifications was only called for conditions still pending, but
an idle notification needs a check 500ms+ after the condition first held
(Frame.IdleNotification). On a quiet page the same tick both starts that
hold and resolves the condition via is_done, so nothing advanced the
state machine for the rest of the wait. The CDP pump waits in 1s slices
(CDP.pageWait), so Page.lifecycleEvent networkIdle/networkAlmostIdle was
starved until a later slice built a fresh condition.

That event is what puppeteer's networkidle0/networkidle2 and
playwright's networkidle block on. Measured with puppeteer against
lightpanda serve, goto(waitUntil: networkidle0) on example.com, median
of 5: 2001ms before, 595ms after (the page loads in ~100ms, so ~600ms is
the floor: load plus the 500ms hold). Every pre-fix run landed within
1999-2195ms - the stall is quantized to whole pump slices, not network
variance. An ad-heavy page is unaffected either way (3196ms vs 2859ms,
overlapping ranges): pending timers keep is_done false, so its condition
never resolved early to begin with.

Non-CDP waits are deliberately unchanged: waitForFrame(.networkidle) on
a quiet page still resolves immediately via is_done rather than serving
the 500ms hold. Agent/MCP waitForState and fetch --wait-until networkidle
want "settled now", not chrome's lifecycle heuristic.
2026-08-07 08:46:06 +02:00
Adrià Arrufat b04c99a911 Merge pull request #3154 from lightpanda-io/tools-backendnodeid-zero
tools: treat backendNodeId 0 as omitted, add recovery hints to errors
2026-08-07 07:36:08 +02:00
Karl Seguin 281a773cad Merge pull request #3090 from lightpanda-io/nikneym/connection-upgrade
Rework `Connection.upgrade` with `header_parser`
2026-08-07 12:23:58 +08:00
Karl Seguin d35aa90959 fix build 2026-08-07 12:00:05 +08:00
Karl Seguin 63a4283989 reset arena after use, verify user input 2026-08-07 11:45:50 +08:00
Karl Seguin 9a35a8b0b1 Merge pull request #3152 from lightpanda-io/fetch-default-load
fetch: default --wait-until to load
2026-08-07 08:43:44 +08:00
Karl Seguin 2e13262622 Merge pull request #3153 from lightpanda-io/fetch-exit-code
main: propagate worker-thread failures to the exit code
2026-08-07 08:37:09 +08:00
Karl Seguin 7107d0e132 webapi: Report CustomElement errors via window.reportError
Per spec, CustomElement creation/upgrade errors should be reported to the window

This also adds more (mostly edge case) validation, such as an element that fails
to be upgraded can never be upgraded again.
2026-08-07 07:37:09 +08:00
Karl Seguin 117f19b3c3 Merge pull request #3148 from lightpanda-io/leaf-node-proto-removal
mem: remove _proto field from leaf nodes
2026-08-07 07:15:39 +08:00
Karl Seguin df084b2cab Merge pull request #3146 from lightpanda-io/style-width-children-aware
render: CSS width/height are now children-content aware
2026-08-07 07:15:23 +08:00
Karl Seguin deb4eb3eef Merge pull request #3155 from lightpanda-io/zenai-bump
build: update zenai dependency
2026-08-07 07:14:57 +08:00
Muki Kiboigo 4f5bcec9a6 add max entry limiting to SqliteCache 2026-08-06 13:29:22 -07:00
Muki Kiboigo e26a200146 add http cache entry limit options 2026-08-06 13:29:05 -07:00
Halil Durak 5b215d7fe9 header_parser: remove OWS off of header values 2026-08-06 19:16:59 +03:00
Halil Durak 92b1eae4c7 introduce header_parser.parseRequest 2026-08-06 19:16:59 +03:00
Halil Durak 82a11ee910 header_parser: add a test block for WS validator 2026-08-06 19:16:58 +03:00
Halil Durak 46ce6cc1dc rework Connection.upgrade with header_parser 2026-08-06 19:16:58 +03:00
Adrià Arrufat 8e3d6adeee build: update zenai dependency
Pulls in the latest three zenai commits:

- f721fd4 feat(retry): honor Retry-After hints on retryable responses
- 103f5e1 feat(retry): treat 408 request timeout as retryable
- 75597b3 feat(types): sync with upstream Go SDK releases
2026-08-06 14:24:11 +02:00
Adrià Arrufat e69aedea14 tools: treat backendNodeId 0 as omitted, add recovery hints to errors
Some models (gpt-5.x via codex) zero-fill optional tool params instead
of omitting them, so every tree/markdown/html call carried
backendNodeId: 0, failed with NodeNotFound, and got retried blind --
one 'go to hacker news' burned 19 tool calls and 18 full page loads.

Registry ids start at 1, so 0 can never name a real node. Make
0-means-omitted part of the tool contract: state it in the schema
descriptions and normalize it in parseValue. Required ids
(nodeDetails) are untouched.

In-band guidance alone was not enough -- the model re-emitted the
identical call even when the error spelled out the fix -- but keep it
for genuinely stale ids: NodeNotFound and FrameNotLoaded now carry an
actionable message in the agent, slash-command, and MCP paths instead
of a bare error name.
2026-08-06 14:20:34 +02:00
Adrià Arrufat ce36e3880e Merge pull request #3151 from lightpanda-io/run-subcommand-docs
docs: prefer `lightpanda run` for replaying scripts
2026-08-06 13:55:49 +02:00
Adrià Arrufat 11b1609cf4 main: propagate worker-thread failures to the exit code
fetchThread and mcpThread caught their errors, logged fatal, and
returned void; the main thread joined and exited 0. A fetch whose
--wait-selector timed out (or any lp.fetch/browser-init error) printed
$level=fatal and still reported success to the shell. Same for mcp
stdio errors, and for three fatal paths in the mcp HTTP branch that ran
on the main thread and returned void.

Threads now hand the error back through an out-pointer (the agentThread
failed/cancelled pattern) and the dispatch returns it after join; the
mcp main-thread paths return their errors directly.

Clean mcp stdin EOF is unaffected: processRequests returns normally on
EOF (router.zig takeDelimiter orelse break), so only real failures
reach the exit code.

Out of scope: a failed navigation in fetch still exits 0 by design —
it renders the synthetic "Navigation failed" error page and dumps it;
--json carries the status for detection.
2026-08-06 13:35:02 +02:00
Adrià Arrufat d79fb2fa6c fetch: default --wait-until to load
The implicit default was done (full quiescence), capped at --wait-ms.
Pages with constant background activity (ad timers, live sockets) never
go quiescent, so every default fetch of such a page silently rode the
full 5s cap; the timeout is non-fatal (Runner.waitForAll discards
WaitResult.timeout), so the default was effectively "wait 5s, then dump
whatever is there". load matches the agent/MCP default_nav_wait and its
rationale.

Measured on an ad-heavy news hub (ReleaseFast, interleaved runs):
default now ~3.2s vs 5.8-5.9s with done, with the load-time dump
containing slightly more of the extracted content, not less (the extra
seconds of ad-script execution mutate the page, they do not add to it).
A quiet page dumps byte-identical output under both.

Explicit --wait-until done|networkidle and --wait-selector/--wait-script
are unchanged; the fetch() doc comment now describes when error.Timeout
can actually be raised (selector/script phases only).
2026-08-06 13:22:48 +02:00
Adrià Arrufat 23c8f04b1f Merge pull request #3149 from lightpanda-io/tools-unknown-name-in-band
tools: surface unknown tool names in-band
2026-08-06 13:02:37 +02:00
Adrià Arrufat 78f24b5da5 docs: prefer lightpanda run for replaying scripts
The `run` subcommand is the intended way to replay a recorded
PandaScript (`agent <script>.js` still works, but `run` carries no LLM
options and states the intent). Update the generated script-writing
skill, the recorder doc comment, and the README accordingly.
2026-08-06 13:02:17 +02:00
Karl Seguin 93bcf5c93a cdp: add request post data
Fixes https://github.com/lightpanda-io/browser/issues/3141

We now capture request body provided they are <= 64KB (arbitrary limit, we can
revisit, but this doesn't seem to be an overly common request and this pins
the bodies in memory until frame end, so I wanted to take it slowly).

Adds Network.getRequestPostData and the `postData` and the `postDataEntries`
fields to the Request object.
2026-08-06 18:44:59 +08:00