Commit Graph
9814 Commits
Author SHA1 Message Date
Adrià Arrufat 1f582d4674 cli: report usage errors once, accept -h, show tips only on a terminal
A flag given without its value, or an extra positional, failed with
only `FATAL exit err=MissingArgument`, not naming the flag. The parser
now logs which flag is missing its value or which argument is extra,
with a hint pointing at the command's help, and a missing fetch URL is
caught while parsing, next to run's missing script. Since each of these
is logged where it's found, main exits without the generic `exit` line.

`-h` works wherever `--help` does, instead of being taken as a URL.

The --obey-robots tip is for a person at a terminal, so it's skipped
when stderr isn't one; scripts capturing stderr no longer get it on
every run.
2026-09-26 23:52:34 +02:00
Karl Seguin 64b14b23e6 Merge pull request #3639 from lightpanda-io/goto-pending-connection
Don't resolve a navigation queued on a free connection as loaded
2026-09-26 07:21:44 +08:00
Karl Seguin 989ad39a47 Merge pull request #3628 from lightpanda-io/iterative-axnode
mem: AXNode tree/query walks iterative, isIgnore linear
2026-09-26 06:12:45 +08:00
Karl Seguin e4e95cf3cb Merge pull request #3627 from lightpanda-io/recycling-allocator
mem: replace slab allocator
2026-09-26 06:06:39 +08:00
Pierre Tachoire 6f18cfcae7 Merge pull request #3632 from lightpanda-io/robots-log-level
ops: downgrade error.RobotsBlocked to warn (from err)
2026-09-25 15:17:22 +02:00
Adrià Arrufat d77c6fb1ca Don't resolve a navigation queued on a free connection as loaded
The easy-handle pool is shared by every client in the process. When other
sessions hold all of it, a new navigation's request sits in pending_queue,
but Runner resolved a frame still in `.pre` as soon as in-flight activity
was zero, which ignores pending transfers. goto then reported success on
an empty document.

Wait on `activity.idle()` instead, and make a goto that times out before
any response arrives a NavigationTimeout error rather than a soft timeout.

Fixes #3636
2026-09-25 15:17:19 +02:00
Adrià Arrufat 8702e06167 Merge pull request #3630 from lightpanda-io/prompt-audit-cleanup
agent: drop dated prompt patterns, bump zenai
2026-09-25 11:35:59 +02:00
Adrià Arrufat efc239bbe8 Merge pull request #3613 from lightpanda-io/scroll-text-extent
Measure wrapped text in an element's content height
2026-09-25 11:20:28 +02:00
Adrià Arrufat ec31d4b711 Merge branch 'main' into prompt-audit-cleanup
# Conflicts:
#	build.zig.zon
#	src/browser/tools.zig
2026-09-25 11:13:12 +02:00
Adrià Arrufat 3ba2a5fffa Merge pull request #3597 from lightpanda-io/agent-fixes
Agent and tool-layer fixes found by a decision-model loop
2026-09-25 10:58:32 +02:00
Adrià Arrufat b5896c259b Merge branch 'main' into agent-fixes
# Conflicts:
#	build.zig.zon
#	src/SemanticTree.zig
2026-09-25 10:44:05 +02:00
Karl Seguin 3d74a90f71 Merge pull request #3633 from lightpanda-io/v8-string-writeutf8
v8: update for changes to v8__String__WriteUtf8
2026-09-25 12:11:42 +08:00
Karl Seguin db98e85ce3 v8: update for changes to v8__String__WriteUtf8
https://github.com/lightpanda-io/zig-v8-fork/pull/211
2026-09-25 11:52:42 +08:00
Karl Seguin 42e593e49f remove unused deinit 2026-09-25 10:53:13 +08:00
Karl Seguin 3f7662dc98 ops: downgrade error.RobotsBlocked to warn (from err) 2026-09-25 10:41:27 +08:00
Karl Seguin a720a51987 Merge pull request #3631 from lightpanda-io/orderfile-regen
orderfile: regenerate the hot-code profile
2026-09-25 09:37:48 +08:00
Karl Seguin ddda5a4bc6 Merge pull request #3612 from lightpanda-io/cascade-box-size
Resolve width and height from stylesheet rules
2026-09-25 09:37:29 +08:00
Karl Seguin 140b0bc908 Merge pull request #3626 from lightpanda-io/style-groups
Split the style cascade into property groups
2026-09-25 09:30:42 +08:00
Karl Seguin 070ece06bb Merge pull request #3483 from lightpanda-io/cors-store
Cors Store
2026-09-25 09:17:04 +08:00
github-actions[bot] 07880245b2 orderfile: regenerate the hot-code profile
hot set 16652KB resident at 4KB fault-around: 21492 text, 21950 rodata symbols
2026-09-25 01:01:57 +00:00
Karl Seguin 722241fe0d Merge pull request #3622 from lightpanda-io/keep-preload-script-errors
http: preserve preload script errors
2026-09-25 06:14:25 +08:00
Karl Seguin 2bd46136dc Merge pull request #3621 from lightpanda-io/legacy-constructors
webapi: Legacy constuctor API
2026-09-25 06:13:23 +08:00
Karl Seguin bfbc34bffa Merge pull request #3619 from lightpanda-io/sanitizer-usage
webapi: Sanitizer API usage
2026-09-25 06:13:06 +08:00
Karl Seguin 1950a81753 Merge pull request #3617 from lightpanda-io/iterative-semantic-tree
mem: SemanticTree and AXNode recursive walk -> iterative
2026-09-25 06:12:53 +08:00
Muki Kiboigo acd71e5f29 collect allowed headers from response 2026-09-24 12:30:44 -07:00
Muki Kiboigo 6aa0fffab3 collectAuthoredHeaders just once in CorsGate 2026-09-24 12:29:57 -07:00
Muki Kiboigo 4957d109d3 use coversRequest everywhere in CorsStore 2026-09-24 12:26:24 -07:00
Muki Kiboigo ee2b97d9f8 fix ordering of store help entries 2026-09-24 12:24:54 -07:00
Adrià Arrufat 6d6f19d6ed tools: fill out under-described tool descriptions
tree, interactiveElements, structuredData, detectForms and scroll were
one or two sentences, and evaluate's script parameter had none. MCP
clients that drop the server instructions only see these, so state what
each returns (fields, shapes, empty cases), when to reach for it over
its neighbours, and scroll's absolute-position semantics.
2026-09-24 20:47:29 +02:00
Adrià Arrufat b5a30be076 build: bump zenai
Picks up effort=none sending thinking disabled to Anthropic (zenai#19)
and the reasoning max_tokens floor on every provider (zenai#18).
ErrorDetail now carries the parsed error message instead of the raw
body.
2026-09-24 20:43:11 +02:00
Adrià Arrufat ff6a54ba22 agent: drop dated prompt patterns
- Synthesis prompt: drop the one-word/one-phrase answer clamp (a
  benchmark format applied to every budget-exhausted REPL turn) and the
  no-more-tools line the request already enforces; keep the
  report-don't-confabulate rule.
- Driver guidance: drop the HN/Reddit source heuristic, which also
  reached every MCP client.
- Save prompt: state the comment rule once instead of repeating it in
  the output-format line.
- goto: describe when it returns, what it returns, and when a url-taking
  read is the better call.
2026-09-24 20:38:39 +02:00
Adrià Arrufat 0d3dfa50f8 AXNode: simplify iterative walks and scope the ignore cache to one call
The list marker is written by writeNode, so writeTree and walkQuery share
one loop shape. IgnoreCache lives on its own pooled arena for the call
instead of frame.call_arena, which only resets on JS calls. The scan no
longer caches its root, which is never asked about again.
2026-09-24 16:16:25 +02:00
Adrià Arrufat 555415da88 perf: memoize AXNode isIgnore for generic containers
A div/span with no role or label is ignored unless a non-ignored node
sits under it through other generic containers. The tree writer asks
that of every node, so each generic container rescanned the chain below
it: O(depth²). A 20k-deep div chain took 5.5s in getFullAXTree.

Answers are now cached per walk. A scan marks every generic container it
enters as ignored, then flips the ones on the path to the exposed node
it stops at. Later questions hit the cache, so the walk is linear:
20k-deep chain 5.5s -> 12.5ms, 2k-deep 46ms -> 1.3ms (ReleaseFast).
Output is byte-identical.
2026-09-24 16:02:16 +02:00
Adrià Arrufat 140bedf39f mem: AXNode tree, query and isIgnore walks -> iterative
Follow-up to the SemanticTree change: the CDP accessibility writer still
recursed once per DOM level in writeNodeChildren (getFullAXTree /
getPartialAXTree), walkQuery (queryAXTree) and isIgnore (chains of
generic div/span containers). In a debug build, a 100k-deep chain
overflows the 8MB main-thread stack in the tree writer and in isIgnore.

The tree and query walks now share an allocation-free pre-order Walker
that counts aria-hidden ancestors instead of threading the flag through
the recursion. isIgnore splits into a shallow per-node verdict
(ignoreSelf) and a TreeWalker pass over generic containers that skips
ignored subtrees.

Output is byte-identical to the recursive version.
2026-09-24 15:39:16 +02:00
Adrià Arrufat 20b0943a21 Trim comments 2026-09-24 13:40:01 +02:00
Adrià Arrufat 822eb1c2f6 Measure wrapped text in an element's content height
A box whose content is only text had no content extent, so its scroll
offset never clamped. With an explicit width, direct text children now
wrap at it and add their lines to the content height.
2026-09-24 13:40:01 +02:00
Adrià Arrufat 20b7325e13 Resolve width and height from stylesheet rules
An element sized by a stylesheet rule had no explicit size, so its scroll
offset never clamped. The geometry group now tracks width and height, and
getElementAxis reads them from the cascade, which already folds in the
inline style. html and body read only their inline size, without
materializing the style object. Removes the now unused
CSS.parseDimensionViewport.
2026-09-24 13:39:55 +02:00
Adrià Arrufat 2ce2fe94df Reset the groups in a loop and trim comments
rebuildIfDirty walks group_fields like the other per-group code, so a new
group needs no change there. Capacities moves out of Group since it
doesn't depend on the spec. Also updates the ownProps and compute call
sites to the (el, frame) order.
2026-09-24 13:39:25 +02:00
Adrià ArrufatandKarl Seguin e547657ab0 Apply batched suggestions from code review
Co-authored-by: Karl Seguin <karlseguin@users.noreply.github.com>
2026-09-24 13:36:45 +02:00
Karl Seguin c3f1314fea mem: replace slab allocator
The slab allocator was meant to enable efficient re-use of freed memory. In
reality, the allocations made to it are rarely freed:

```
│         site          │ allocs │ freed │
│ reddit /r/programming │ 50,462 │ 4.6%  │
│ wikipedia article     │ 8,557  │ 3.4%  │
│ youtube               │ 4,913  │ 9.5%  │
│ bbc news              │ 4,734  │ 1.1%  │
│ github repo           │ 4,117  │ 3.3%  │
│ react.dev             │ 3,640  │ 0.3%  │
│ HN                    │ 1,313  │ 0.1%  │
```

And, just because allocations are freed doesn't meant that memory gets to be
re-used. reddit has HTMLCollection 1120 total HTMLCollection allocation, with
a peak inflight of 862, so the majority of frees weren't useful.

I think the ArenaPool came after the slab, and it became the preferred (but not
exclusive) mechanism for managing eagerly freed memory.

This replaces the slab allocator with a simpler recycler. Unlike the slab, it
doesn't degrade in performance as the # of allocations grow (310ns/op vs 17ns/op
at 500K items) and it doesn't leak memory (the parent allocator *is* the page's
arena, so the Slab's bitset growth will leak unless it can grow in place).
2026-09-24 17:54:45 +08:00
Karl Seguin 7f4387b9c7 Merge pull request #3623 from lightpanda-io/delete-fs-cache
chore: delete FsCache.zig, it isn't being used
2026-09-24 15:29:08 +08:00
Karl Seguin 40cf2b28c3 Merge pull request #3624 from lightpanda-io/response-header-normalization
http: lowercase response headers
2026-09-24 15:28:59 +08:00
Karl Seguin 7e2fcec7c7 Merge pull request #3625 from lightpanda-io/speed-up-slow-tests
dev: speed up some slow tests
2026-09-24 15:28:48 +08:00
Karl Seguin 606089f5a8 Merge pull request #3620 from lightpanda-io/new-options
webapi: add new Option() support
2026-09-24 15:28:28 +08:00
Karl Seguin b8175662df Merge pull request #3606 from lightpanda-io/default-indexer-query
webapi: give every indexer implementation a query handler
2026-09-24 15:27:54 +08:00
Adrià Arrufat 8d62739503 Split the style cascade into property groups
Each group owns its rule buckets, its memo and its cascade priorities, so a
rule only joins the groups it declares something in. Visibility keeps
display, visibility, opacity and pointer-events; overflow and
overscroll-behavior move to a geometry group. A visibility probe no longer
matches overflow-only rules, and its memo entry shrinks to 6 bits.
2026-09-24 09:24:28 +02:00
Karl Seguin e3912ba208 dev: speed up some slow tests
-TCP_NODELAY on test clients,
-WebDrive tests poll for completion with a short sleep, instead of 1 long one
-reduce isolated world redirect delay
2026-09-24 13:59:34 +08:00
Karl Seguin e5ecdf1fe3 http: lowercase response headers
Response headers get lower cased once, upfront. Any consumer of a transfer's /
response's headers is now `mem.eql` rather than `ascii.eqlIgnoreCase`. This
fixes 1 or 2 WPT cases (e.g. XHR's `getAllResponseHeaders`), it also mergers
values in some cases (which is generally correct) - we need a follow up PR
to correctly merge in all cases.
2026-09-24 13:51:41 +08:00
Karl Seguin 1b38dd16b7 chore: delete FsCache.zig, it isn't being used 2026-09-24 13:08:39 +08:00
Karl Seguin 5b994c10cd http: preserve preload script errors
Preloaded modules would discard errors in the hope that re-fetching the script
when it was needed, might work. This reverses that decision and stores the
error state. When a preload fails, that failure sticks.

This does mean that a transient failure doesn't get a second chance.

But it also means we don't log the failure multiple times (I noticed this when
using adblocking and seeing duplicate failures for the same endpoint). Since we
don't keep trying, it cuts down the CDP flow too.
2026-09-24 12:51:51 +08:00