We need to remove v8 finalizer callbacks upfront so that, as we tear things down
there's no chance for v8 to try to finalize something which has already been
finalized or is gone.
Implement the XHR timeout property end-to-end: the JS-visible
getter/setter stores the value, send() passes it to the HTTP client,
and curl enforces it via CURLOPT_TIMEOUT_MS. On timeout, a `timeout`
event is dispatched instead of `error`, per the XHR spec.
Both MCP tools.zig and agent ToolExecutor.zig duplicated the same 20 tool
handlers. This extracts the shared logic into src/browser/tools.zig so new
tools only need to be added once. Reduces total code by ~620 lines while
keeping all 465 tests passing.
This is standalone work that can be done to enable workers. Workers need a
subset of EventManager, specifically, dispatching events for non DOM objects.
This commit extracts the non-DOM dispatching into an EventManagerBase which
EventManager uses (via composition) and which, in the future, WorkerGlobalScope
will be able to use directly.
Dialogs auto-dismiss in headless mode, so there is no pending dialog
by the time the CDP client sends Page.handleJavaScriptDialog. Return
an explicit error so the client knows the action had no effect.
parseDomain() rejects bare TLDs (e.g. Domain=.io) but accepts
multi-level public suffixes like .co.uk, .com.au, .co.jp.
Per RFC 6265bis §5.7.3.10, user agents should reject cookies whose
domain attribute is a public suffix. Chrome, Firefox, and Safari all
enforce this using the Public Suffix List.
The PSL data is already imported (Cookie.zig:26) and used in
findSecondLevelDomain(), but parseDomain() does not consult it.
This causes behavior differences vs Chrome when automating .co.uk /
.com.au / .co.jp sites via CDP — cookies that Chrome silently drops
are accepted by Lightpanda, polluting the cookie jar across unrelated
sites in the same session.
- Add Recorder for recording REPL sessions to .panda files, with
--no-record flag and positional file arg support. Skips read-only
commands (WAIT, TREE, MARKDOWN) per spec.
- Record resolved LLM tool calls as Pandascript commands so the
generated artifact is deterministic.
- Add self-healing in --run mode: on command failure, prompt the LLM
with the # INTENT context to resolve an alternative.
- Add LOGIN and ACCEPT_COOKIES high-level commands (LLM-resolved).
- Add multi-line EVAL """...""" support via ScriptIterator.
- Add $VAR_NAME environment variable substitution in command arguments.
- Escape JS strings in execType/execExtract to prevent injection.
- Sanitize output file paths in EXTRACT to prevent path traversal.