Commit Graph

4756 Commits

Author SHA1 Message Date
Adrià Arrufat
6e7c8d7ae2 mcp: consolidate tests and streamline parameter parsing 2026-03-02 22:18:02 +09:00
Adrià Arrufat
3c858f522b mcp: simplify minify function 2026-03-02 22:04:55 +09:00
Adrià Arrufat
f2a30f8cdd mcp: don't forget to flush 2026-03-02 21:46:49 +09:00
Adrià Arrufat
43785bfab4 mcp: simplify handleList implementations 2026-03-02 21:30:47 +09:00
Adrià Arrufat
78edf6d324 mcp: simplify I/O architecture and remove test harness 2026-03-02 21:25:07 +09:00
Adrià Arrufat
73565c4493 mcp: optimize dispatching and simplify test harness
- Use StaticStringMap and enums for method, tool, and resource lookups.
- Implement comptime JSON minification for tool schemas.
- Refactor router and harness to use more efficient buffered polling.
- Consolidate integration tests and add synchronous unit tests.
2026-03-02 20:53:14 +09:00
Pierre Tachoire
ca0ef18bdf Implement async piping for ReadableStream.pipeThrough/pipeTo
Replace synchronous queue-draining approach with async promise-based
piping using V8's thenAndCatch callbacks. PipeState struct manages the
async read loop: reader.read() returns a Promise, onReadFulfilled
extracts {done, value}, writes chunks to the writable side, and
recurses via pumpRead() until the stream closes.
2026-03-02 12:17:17 +01:00
Pierre Tachoire
6ed011e2f8 Add pipeThrough and pipeTo to ReadableStream
Implement synchronous piping that drains queued chunks from a
ReadableStream into a WritableStream. pipeThrough accepts any
{readable, writable} pair (TransformStream, TextDecoderStream, etc.)
and returns the readable side. pipeTo writes all chunks to a
WritableStream and resolves when complete.
2026-03-02 12:06:18 +01:00
Pierre Tachoire
23d322452a Add TextDecoderStream to decode UTF-8 byte streams into strings
Mirrors TextEncoderStream: wraps a TransformStream with a Zig-level
transform that converts Uint8Array chunks to strings. Supports the
same constructor options as TextDecoder (label, fatal, ignoreBOM).
2026-03-02 11:49:01 +01:00
Pierre Tachoire
5d3b965d28 Implement WritableStream, TransformStream, and TextEncoderStream
Add the missing Streams API types needed for TextEncoderStream support:
- WritableStream with locked/getWriter, supporting both JS sink callbacks
and internal TransformStream routing
- WritableStreamDefaultWriter with write/close/releaseLock/closed/ready
- WritableStreamDefaultController with error()
- TransformStream with readable/writable accessors, JS transformer
callbacks (start/transform/flush), and Zig-level transform support
- TransformStreamDefaultController with enqueue/error/terminate
- TextEncoderStream that encodes string chunks to UTF-8 Uint8Array
via a Zig-level transform function
2026-03-02 11:49:01 +01:00
Karl Seguin
d9794d72c7 fix bad rebase 2026-03-02 18:39:02 +08:00
Karl Seguin
524b5be937 on iframe re-navigation, keep pending_loads in sync 2026-03-02 18:14:36 +08:00
Karl Seguin
ac2e276a6a try to make test more stable 2026-03-02 18:14:36 +08:00
Karl Seguin
4f4dbc0c22 Allow iframe.src to renavigate the page
Unlike a script, an iframe can be re-navigated simply by setting the src.
2026-03-02 18:14:34 +08:00
Karl Seguin
8c37cac957 Merge pull request #1694 from lightpanda-io/client_abort_frame
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
e2e-test / browser fetch (push) Has been cancelled
zig-test / zig test using v8 in debug mode (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / zig build release (push) Has been cancelled
wpt / build wpt runner (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
e2e-integration-test / zig build release (push) Has been cancelled
e2e-integration-test / demo-integration-scripts (push) Has been cancelled
Allow frame-specific HTTP abort
2026-03-02 18:11:33 +08:00
Karl Seguin
eceab76b6f Merge pull request #1693 from lightpanda-io/nikneym/arena-pool-test
`ArenaPool`: make init configurable + add tests
2026-03-02 18:11:13 +08:00
Karl Seguin
1f81b6ddc4 Allow frame-specific HTTP abort
Needed for frame navigation. Implemented using some ugly comptime to avoid
duplication and avoid an runtime frame check when doing a full abort.
2026-03-02 18:00:55 +08:00
Halil Durak
52c3aadd24 ArenaPool: add tests 2026-03-02 12:56:10 +03:00
Halil Durak
ad87573d09 ArenaPool: make init configurable 2026-03-02 12:55:55 +03:00
Karl Seguin
20fbfc8544 Merge pull request #1689 from lightpanda-io/protect_xhr_abort_during_callback
Protect against transfer.abort() being called during callback
2026-03-02 17:42:07 +08:00
Karl Seguin
7695c8403f Merge pull request #1692 from lightpanda-io/rename_page_id_to_frame_id
Rename page.id to page._frame_id
2026-03-02 17:40:43 +08:00
Karl Seguin
421983d06e Merge pull request #1690 from lightpanda-io/event_dispatch_cleanup
Attempt to improve non-DOM EventTarget dispatching
2026-03-02 17:40:29 +08:00
Karl Seguin
328c681a8f Add transfer-specific "performing" flag
In the previous commits, two separte crash resolution conspired to introduce
1 tick delay in request handling.

When we're in a libcurl perform, we can't re-enter libcurl. So we added a
check before processing new requests to make sure we weren't "performing" and,
if we were, we'd queue the request (hence the 1 tick delay).

But for another issue, we set the same "performing" check when manually
triggering callbacks. This extended the situations where the above check fired
thus causing the 1-tick delay to happen under more (and even common) situation.

This commit improves this - instead of relying on the global "performing" check
when processing 1 transfer explicitly, we now have a per-transfer performing
check. This prevents the transfer from being deinitialized during a callback
but does not block requests from being started immediately.
2026-03-02 17:29:47 +08:00
Pierre Tachoire
48d94d0f68 Merge pull request #1688 from lightpanda-io/cdp_shutdown
Remove redundant CDP v8 shutdown
2026-03-02 09:35:40 +01:00
Karl Seguin
10ad5d763e Rename page.id to page._frame_id
This field was recently added and is used to generate correct frameIds in CDP
messages. They remain the same during a navigation event, so calling them
page.id might cause surprises since navigation events create new pages, but
retain the original id. Hence, frame_id is more accurate and hopefully less
surprising.

(This is a small cleanup prior to doing some iframe navigation work).
2026-03-02 16:21:29 +08:00
Pierre Tachoire
2a78c946e4 Merge pull request #1691 from lightpanda-io/wpt-timeout
adjust WPT timeout on CI
2026-03-02 09:14:50 +01:00
Adrià Arrufat
a7872aa054 mcp: improve robustness of server and test harness
- Refactor router and test harness for non-blocking I/O using buffered polling.
- Implement reliable test failure reporting from sub-threads to the main test runner.
- Encapsulate pipe management using idiomatic std.fs.File methods.
- Fix invalid JSON generation in resource streaming due to duplicate fields.
- Improve shutdown sequence for clean test exits.
2026-03-02 17:03:04 +09:00
Pierre Tachoire
5c228ae0a1 adjust WPT timeout on CI 2026-03-02 08:58:03 +01:00
Karl Seguin
ce73f7ac5a Attempt to improve non-DOM EventTarget dispatching
There are two main ways to dispatch events, both via the EventManager: dispatch
and dispatchWithFunction. dispatchWithFunction came about from having to
dispatch to function callbacks in addition to event listeners. Specifically,
firing the window.onload callback.

Since that original design, much has changed. Most significantly, with
https://github.com/lightpanda-io/browser/pull/1524 callbacks defined via
attributes became properly (I hope) integrated with the event dispatching.
Furthermore, the number of non-tree event targets (e.g. AbortSignal) has grown
significantly. Finally, dispatching an event is DOM-based event is pretty
complex, involving multiple phases and capturing the path.

The current design is largely correct, but non-obvious. This commit attempts to
improve the ergonomics of event dispatching.

`dispatchWithFunction` has been renamed to `dispatchDirect`. This function is
meant to be used with non-DOM event targets. It is optimized for having an event
path with a single target andh no bubbling/capture phase. In addition to being
a little more streamlined, `dispatchDirect` will internally turn a
`js.Function.Global` or `js.Function.Temp` into a local. This makes the callsite
simpler, but also provides optimization opportunity - not having to create
a new scope for the common case of having no callback/listener. This lays the
groundwork for having a `hasDirect` guard clause at the callsite to avoid
unnecessary event creation (todo in a follow up commit).

`dispatch` remains unchanged. While `dispatch` is primarily meant to handle the
DOM-based EventTarget, it will forward non-DOM EventTargets to `dispatchDirect`.
This is necessary since JS code can call `signal.dispatchEvent(....)`.

Two notes:
1 - The flow of dispatchDirect is an optimization. The spec makes no distinction
    between DOM and non-DOM based EventTargets.
2 - While the window (as an EventTarget) should probably be thought of as a
    DOM-based EventTarget, we use `dispatchDirect with it. This is because it
    sits at the root and thus can safely go through the faster `dispatchDirect`.
2026-03-02 15:11:02 +08:00
Adrià Arrufat
64107f5957 mcp: refactor for testability and add comprehensive test suite
- Refactor mcp.Server and router to accept injected I/O streams.
- Implement McpHarness for high-fidelity MCP integration testing.
- Add unit tests for protocol, tools, and resources modules.
- Add integration tests covering initialization, tool/resource execution, and error handling.
- Improve error reporting for malformed JSON requests.
2026-03-02 15:52:05 +09:00
Adrià Arrufat
8a1795d56f mcp: fix memory leak in links tool 2026-03-02 13:09:58 +09:00
Karl Seguin
b104c3bfe8 Don't start request during callback
Fixes a separate but similar issue to
https://github.com/lightpanda-io/browser/pull/1689

Specifically, it prevents starting a request from within a libcurl handler, thus
avoiding an illegal recursive call.

(This commit also removes the failed function call debug logging for
DOMExceptions, as these aren't particularly abnormal / log-worthy)
2026-03-02 12:04:02 +08:00
Karl Seguin
82e3f126ff Protect against transfer.abort() being called during callback
This was already handled in most cases, but not for a body-less response. It's
safe to call transfer.abort() during a callback, so long as the performing flag
is set to true. This was set during the normal libcurl callbacks, but for a
body-less response, we manually invoke the header_done_callback and were not
setting the performing flag.
2026-03-02 11:44:42 +08:00
Adrià Arrufat
175488563e mcp: remove browser message loop from processRequests 2026-03-02 12:25:33 +09:00
Adrià Arrufat
da51cdd11d Merge branch 'main' into mcp 2026-03-02 11:55:36 +09:00
Adrià Arrufat
a8a47b138f mcp: change browser from pointer to value 2026-03-02 11:50:56 +09:00
Adrià Arrufat
b63d4cf675 mcp: improve RawJson stringification and schema formatting
- Update `RawJson.jsonStringify` to parse and re-write JSON content, ensuring valid output.
- Reformat tool input schemas in `tools.zig` using multi-line string literals for better readability.
2026-03-02 11:47:02 +09:00
Karl Seguin
03b999c592 Remove redundant CDP v8 shutdown
https://github.com/lightpanda-io/browser/pull/1614 improved our shutdown
behavior so that microtasks associated with a context wouldn't fire after the
context was disposed of. This involved having context-specific microtasks,
pumping the message loop, and prevent re-entry.

The shutdown code in CDP already had much of this behavior built-in, but it has
now become redundant. Most importantly the CDP shutdown logic did not prevent
re-entry.

Removing this code fixes a flaky WPT crash. I didn't seem to be tied to a
specific test, but rather a cross-context/page use-after-free that was saw
prior to 1614. I could reproduce it reliably by running `/wasm/core/`.

I'll be honest, it isn't clear to me why _removing_ the CDP cleanup helps.
Running the message loop and microtask _before_ our normal shutdown might be
unnecessary, but why would it crash? I don't know, but the CDP path is slightly
different in that it also involves Inspector shutdown. So there's still
something about this flow I don't quite understand. And, at least for this case
the current flow seems "correct".
2026-03-02 10:24:07 +08:00
Adrià Arrufat
a91afab038 mcp: improve event loop and response handling
- Use an allocating writer in `sendResponse` to handle large payloads.
- Update the main loop to tick the HTTP client and cap poll timeouts.
- Update protocol version and minify tool input schemas.
2026-03-02 11:12:00 +09:00
Adrià Arrufat
d4747b5386 mcp: own the browser
Co-authored-by: Karl Seguin <karlseguin@users.noreply.github.com>
2026-03-02 10:10:08 +09:00
Adrià Arrufat
41b81c8b05 mcp: use io poll for stdin and integrate message loop
Replaces blocking stdin reads with `std.io.poll` to allow macrotasks to
run. Removes the stdout mutex as I/O is now serialized.
2026-03-02 10:04:23 +09:00
Pierre Tachoire
552831364d Merge pull request #1687 from lightpanda-io/ci-integration-test
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
e2e-test / browser fetch (push) Has been cancelled
zig-test / zig test using v8 in debug mode (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / zig build release (push) Has been cancelled
wpt / build wpt runner (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
e2e-integration-test / zig build release (push) Has been cancelled
e2e-integration-test / demo-integration-scripts (push) Has been cancelled
ci: reduce log_level for integration test
2026-03-01 16:09:56 +01:00
Adrià Arrufat
42b5e32473 mcp: modernize I/O processing and reuse message buffer 2026-03-01 22:35:28 +09:00
Adrià Arrufat
e9c36fd6f8 mcp: use declarative static definitions for tools and resources 2026-03-01 21:56:48 +09:00
Adrià Arrufat
952dfbef36 mcp: use acquire/release ordering for server running flag 2026-03-01 21:39:38 +09:00
Adrià Arrufat
254984b600 mcp: use dynamic allocation for error messages in tools 2026-03-01 21:36:21 +09:00
Adrià Arrufat
8cbc58d257 mcp: unify error reporting and use named error codes 2026-03-01 21:29:59 +09:00
Adrià Arrufat
e6cc3e8c34 mcp: refactor tools handling 2026-03-01 21:18:28 +09:00
Karl Seguin
516335e0ed Merge pull request #1686 from lightpanda-io/load_event_iframe_fix
Fix load event for page with no external scripts but with iframes
2026-03-01 20:15:36 +08:00
Adrià Arrufat
01798ed7f8 mcp: use sentinel-terminated strings for tool params 2026-03-01 20:58:00 +09:00