Commit Graph

7048 Commits

Author SHA1 Message Date
Adrià Arrufat
62a3e73f25 Merge pull request #2603 from lightpanda-io/agent_repl_pimp
agent: improve banner
2026-06-02 11:50:01 +02:00
Adrià Arrufat
04ee47c268 Merge branch 'agent' into agent_repl_pimp 2026-06-02 11:23:39 +02:00
Adrià Arrufat
401f73b0f2 agent: echo console logs in REPL
Drains and prints console messages during the REPL loop. This ensures
console output is surfaced in JS mode, where slash commands like
`/consoleLogs` are unreachable.
2026-06-02 11:09:53 +02:00
Francis Bouvier
f54359aef6 agent: improve banner 2026-06-02 10:45:19 +02:00
Adrià Arrufat
8e063f8e83 repl: add JS evaluation mode 2026-06-02 10:19:37 +02:00
Adrià Arrufat
12b2375969 terminal: support kitty keyboard protocol
Updates the isocline dependency and enables the kitty keyboard
protocol "disambiguate" mode to support Ctrl+Enter detection.
2026-06-02 09:11:56 +02:00
Adrià Arrufat
818b225d99 Merge branch 'main' into agent 2026-06-02 08:12:26 +02:00
Karl Seguin
1895d8f58d Merge pull request #2329 from lightpanda-io/deferred-layer
Deferred Layer
2026-06-02 12:43:06 +08:00
Karl Seguin
94ba07913c Merge pull request #2584 from lightpanda-io/request_callback_terminate
Improve forced terminate on CDP client disconnect.
2026-06-02 11:10:57 +08:00
Karl Seguin
79cdbd285d Improve forced terminate on CDP client disconnect.
Depends on https://github.com/lightpanda-io/zig-v8-fork/pull/179

An improvement to https://github.com/lightpanda-io/browser/pull/2515 to prevent
a v8 assertion if we terminate as an inspector dispatch is happening.

The problem is that if we just immediately terminate, we aren't sure what the
worker thread is doing, and, apparently, if we terminate then dispatch a message
to the inspector, we fail an assertion.

With the way the code was, the only safe solution would be to hold a mutex
over the session dispatch, but that could block the network thread.

So instead of terminating from the network thread, we now ask v8 to execute
a callback. This gets executed on the worker thread, which can then terminate
the execution.

The initial version of 2515 delayed the termination from the network thread.
It's possible that solution would "solve" the issue, simply because it's very
unlikely that a worker would be "stuck" for 5 seconds and then get unstuck.
More likely that it exits immediately, or is stuck in an endless loop. But
that would still leave a window where we could terminate in network and then
dispatch in the worker. Less likely, but still possible. Hopefully this new
mechanism eliminates this from being a problem in all circumstances.
2026-06-02 08:27:49 +08:00
Karl Seguin
56181bbe6c Merge pull request #2595 from lightpanda-io/reentrant_stream_parsing
Protect against re-entrant stream parsing
2026-06-02 06:27:37 +08:00
Karl Seguin
4291c549e0 Merge pull request #2592 from lightpanda-io/uaf_queued_navigation_log_failure
Avoid UAF in log message when processFrameNavigation fails
2026-06-02 06:26:22 +08:00
Karl Seguin
58533e1a53 Merge pull request #2591 from lightpanda-io/global_flattening
Global property flattening
2026-06-02 06:25:59 +08:00
Karl Seguin
9251c3d45e Merge pull request #2593 from lightpanda-io/transfer_data_ownership
Clone data into the transfer's arena
2026-06-02 06:25:42 +08:00
Karl Seguin
e333e458b1 Merge pull request #2597 from lightpanda-io/remove_unused_imports
remove unused imports
2026-06-02 06:24:30 +08:00
Adrià Arrufat
29408bda2b deps: update isocline dependency 2026-06-01 23:14:51 +02:00
Adrià Arrufat
2c39b77591 build: update isocline for bracketed paste 2026-06-01 23:03:10 +02:00
Francis Bouvier
0544d732dd Merge pull request #2599 from lightpanda-io/agent_script_js
agent: run recorded scripts as JavaScript
2026-06-01 20:25:21 +02:00
Adrià Arrufat
f507ed902f agent: simplify schema extraction
Consolidates the switch block in `extractArgs` to extract the schema
string first before wrapping it. Simplifies `extractSchemaString` by
reusing `normalizeExtractSchemaString` for array schemas.
2026-06-01 18:41:53 +02:00
Adrià Arrufat
fb22f0e875 agent: use local arenas to avoid re-entrant corruption
Re-entrant JS callbacks (like `toJSON` or `toString`) could reset the
shared `call_arena` mid-flight. Using local arenas prevents this.
2026-06-01 18:33:32 +02:00
Adrià Arrufat
8fbf63fdc9 runtime: fix strict-mode calls and drain microtasks
Use the current isolate context instead of the receiver's context
when invoking primitives, fixing failures in strict-mode scripts.
Also, explicitly perform a microtask checkpoint after running a
script to ensure promise continuations run.
2026-06-01 18:22:40 +02:00
Francis Bouvier
e59c4b2cae Merge pull request #2598 from lightpanda-io/agent-remove-autoheal
refactor: remove legacy PandaScript self-healing and execution
2026-06-01 17:46:31 +02:00
Adrià Arrufat
044b34d228 refactor: remove legacy PandaScript self-healing and execution
Removes the `--self-heal` CLI option, the `scriptStep` and `scriptHeal`
MCP tools, and associated verification/iterator machinery. Replaces
"PandaScript" terminology with "slash commands" and moves shared
helpers to `tools.zig`.

BREAKING CHANGE: The `--self-heal` CLI flag and the `scriptStep` and
`scriptHeal` MCP tools have been removed.
2026-06-01 17:29:24 +02:00
Karl Seguin
37a846d91d remove unused imports 2026-06-01 22:42:39 +08:00
Karl Seguin
4b51808c92 Merge pull request #2594 from lightpanda-io/robots-layer-pending-panic
Remove missing queue panic on RobotsLayer
2026-06-01 22:33:07 +08:00
Adrià Arrufat
cc6ad4d436 refactor: simplify enum usage and remove redundant helpers
- Use `std.enums.values` and `@tagName` in `ScriptRuntime` to eliminate
  the manual `primitive_specs` and `console_specs` arrays.
- Simplify `Primitive.tool()` using `std.meta.stringToEnum`.
- Clean up `writeConsoleLine` and remove `writeJsPositional`.
2026-06-01 16:26:42 +02:00
Karl Seguin
2a96311373 Protect against re-entrant stream parsing
This specifically fixes a crash on WPT:
/html/syntax/parsing/html5lib_scripted_webkit01.html?run_type=write

Claude wrote a simple reproducing unit test, and you can see it's a
document.write that calls document.write.
2026-06-01 22:14:04 +08:00
Adrià Arrufat
dd096cd0c5 Merge branch 'agent' into agent_script_js 2026-06-01 15:57:49 +02:00
Muki Kiboigo
2f1362ac19 remove missing queue panic on RobotsLayer 2026-06-01 06:57:14 -07:00
Francis Bouvier
8824174afa agent: run recorded scripts as JavaScript
Replace recorded agent replay with a standalone JavaScript script runtime.
Install synchronous agent primitives in an isolated V8 context, add console
output, return structured extract values as JS objects/arrays, and route script
execution through the new runtime.

Update recording to emit .js function calls, default /save filenames to .js,
drop script-level extract save support, and refresh agent docs/tutorials for
the new format.

Self-healing is disabled for now.
2026-06-01 15:43:37 +02:00
Muki Kiboigo
5b4b978347 minor cleanup of DeferringLayer 2026-06-01 06:23:43 -07:00
Muki Kiboigo
51d8c8e8d8 prevent double frees on shutdown with DeferredContext 2026-06-01 06:23:43 -07:00
Muki Kiboigo
444884fb81 remove unneeded flushUnblocked 2026-06-01 06:23:42 -07:00
Muki Kiboigo
342ce9b1d9 firePartial should always have a stable response 2026-06-01 06:23:42 -07:00
Muki Kiboigo
673403f950 properly flush frame after syncRequest eval 2026-06-01 06:23:42 -07:00
Muki Kiboigo
9ab82d2761 add DeferringLayer 2026-06-01 06:23:40 -07:00
Karl Seguin
8a76153cbb Clone data into the transfer's arena
There can be cases where the data referenced by Request does not live for the
duration of a Transfer. The most obvious case is a QueuedNavigation..this is
generally a problem, but it's particularly problematic under load when the
request gets queued in the HttpClient.

Most of the data is small, so just _always_ duping it is worth it. The body
can be large, so we provide a flag for callers to set to turn off the body
duping (essentially saying "I promise to keep the body alive for the duration
of the transfer). Currently, only XHR is able to make this guarantee.
2026-06-01 21:20:44 +08:00
Adrià Arrufat
2104de8e6d agent: move slash command helpers to Terminal
Moves `printHelpSection` and `printSlashParseError` from `Agent` to
`Terminal` to consolidate terminal rendering logic.
2026-06-01 15:10:09 +02:00
Adrià Arrufat
03e96d9e8f agent: extract settings and use shared utf8 truncation
Extracts provider and model settings logic from `Agent.zig` into a new
`settings.zig` module. Replaces custom UTF-8 truncation logic with
`truncateUtf8` from `string.zig`. Also updates the `zenai` dependency.
2026-06-01 15:03:42 +02:00
Karl Seguin
58d6e3f389 Avoid UAF in log message when processFrameNavigation fails
When processFrameNavigation fails, we catch the error and log the `qn.url`. But
`qn` has been been freed by this point. This refactors the code to make
`procesFrameNavigation` clearly take ownership of `qn` and of logging any
errors while `qn` is still active.
2026-06-01 19:13:14 +08:00
Adrià Arrufat
e048b4b293 Merge branch 'main' into agent 2026-06-01 12:36:08 +02:00
Adrià Arrufat
38531e1bb5 agent: deduplicate LLM setup hints and checks
Extracts the API key and LLM setup hint strings into reusable constants.
Also refactors the REPL to use the `requireLlm` helper instead of
duplicating the LLM check logic.
2026-06-01 12:32:32 +02:00
Adrià Arrufat
1a7e70fff7 agent: clean up terminal and slash command logic
- Move `atLeast` helper to `AgentVerbosity` enum.
- Simplify `ghostFirstMatch` signature by removing `anytype`.
- Replace pointer-mutating `skipWs` with `skipWhitespace`.
- Convert several comments to doc comments.
2026-06-01 12:19:03 +02:00
Karl Seguin
30f6854820 Global property flattening
Global objects (Window, WorkerGlobalState) should have accessors and functions
defined directly on the global object. This is in addition to having it defined
on the prototype.

This prevents some weird overwriting that scripts can otherwise achieve.
Something I saw on espn where window.navigator was being overwritten by a global
`navigator` variable.
2026-06-01 17:42:19 +08:00
Pierre Tachoire
9712e4171e Merge pull request #2590 from lightpanda-io/SSO_bridge_coercion
Coerce value to strings on string.String (SSO) target
2026-06-01 10:52:04 +02:00
Karl Seguin
ec6748e3ef Merge pull request #2566 from lightpanda-io/import_maps
Improve ImporMap
2026-06-01 15:47:03 +08:00
Karl Seguin
da6d821598 Coerce value to strings on string.String (SSO) target
When `[]const u8` is a web api parameter, we'll coerce the value to a string,
e.g. true -> "true". This is correct for almost every API. APIs can also opt
to use a string.String (or string.String.Global). This is purely meant as an
optimization, but its behavior is currently different than `[]const u8` as the
bridge will only map actual JS strings to it.

This commit makes String and []const u8 behave the same, so that the only
decision as to which to use is about performance.

(APIs that strictly want a string should use js.String or js.Value and do the
type check)
2026-06-01 15:29:32 +08:00
Karl Seguin
9eb229a963 Improve ImporMap
This is driven by import-maps WPT tests. It generally does 3 high level
additions, plus various small compliance tweaks.

1 - Entries with a trailing match are used for prefix matching
2 - Supports scopes (which are entries group into a specific route-like prefix)
3 - Because of the above, resolves in correct order with fallback

Resolution is based on longest-match wins, so it doesn't require a fancy
data structures. We use ordered (by length) slices, and just iterate until we
find a match. Neither our parsing nor our matching is super efficient. While
a page might have hundreds of scripts, it likely has only 0-1 import maps and
relatively few values.

ImportMap.resolve always returns the final URL. So even if a match isn't found
based on the parsed JSON, it'll return the URL.resolve(base, url). Just to make
WPT tests pass, we do have to track invalid entries in the ImportMap, e.g.
"key": "not-a-url". In the previous version, we'd fallback to URL.resolve(base,
url). Now we return null and leave it to the caller to decide.
2026-06-01 15:24:53 +08:00
Karl Seguin
fd228a65f0 Merge pull request #2575 from lightpanda-io/url_tweaks
Improve WPT /url/ tests
2026-06-01 15:18:58 +08:00
Pierre Tachoire
ba9a1a7c72 Merge pull request #2588 from lightpanda-io/about_blank_base_url
An about:blank iframe/popup inherits its parent's base_url
2026-06-01 09:05:38 +02:00