Prints a Braille-art Lightpanda logo alongside the welcome text and
command hints if the terminal is wide enough. Otherwise, falls back
to a text-only layout.
Also exposes `Terminal.displayWidth` to assist with layout calculations.
- Track initialized providers in Agent.zig to avoid freeing garbage
memory on error.
- Discard the rest of the line in mcp router on StreamTooLong to
allow processing subsequent requests.
Moves `tagNames` and `tagHint` from `SlashCommand` to `Config` for reuse.
Adds `tagJsonArray` to dynamically generate JSON enum schemas, and
uses it in `tools.zig` for the `WaitUntil` enum.
Avoids network round trips during agent startup to keep it snappy.
Skips model reconciliation in REPL mode and loads the model-list
cache lazily instead of pre-warming it.
Removes the `waitUntil` option from `goto` and other navigation tools,
making them default to the fast `load` event. Introduces a dedicated
`waitForState` tool to wait for specific load states on demand.
Adds support for `/provider null` to disable the LLM and persist this
preference in `.lp-agent.zon`. Subsequent REPL launches will start
in basic mode without prompting for API keys. Transient `--no-llm`
runs do not clobber the saved provider.
Passes WPT /html/webappapis/atob/base64.html
Two changes
1 - Use the forgiving decoder already in data_url
2 - Coerce input (3 => "3")
The 2nd change was more interesting. These take a js.String.OneByte as an
optimization, which doesn't coerce. To preserve this optimization a union was
used with a `raw: []const u8` fallback (and our bridge always coerces to
a `[]const u8`)
Adds instructions on using `url` parameters with `markdown`, `tree`,
and `html` to avoid redundant `goto` calls. Also adds a section on
browsing efficiently to minimize page loads and triage search results.
- `/clear` forgets conversation history, usage, and node IDs while
keeping the loaded page and cookies.
- `/reset` does a full reset, starting a fresh browser session.
Just a random test I happen to see in WPT, 0/99 -> 99/99:
/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.worker.html
This limit isn't about correctness,it's just about making sure a test doesn't
block forever. 2 seconds does seem like plenty of time, but I'm thinking it's a
slow/busy CI. If it still happens after this bump, could mean there's an actual
issue.
The first is with WGS not flushing the deferring layer after its synchronous
importScripts call, see: https://github.com/lightpanda-io/browser/pull/2329#discussion_r3271068955
The second is from the ability of an XHR request to be re-used. This was gated
on a boolean, but the ordering means that the 1st requests' released gets
blocked by the gate, and thus we're always 1 release short. The solution is to
use a counter instead of a boolean.
Updates documentation to clarify that script primitives use CSS
selectors instead of backendNodeIds. Explains how to use `/nodeDetails`
to get selectors. Clarifies the difference in `/save` behavior
between `--no-llm` and LLM modes.
Updates agent-related documentation to reflect recent changes:
- Removes obsolete `follow` option from `extract` schema.
- Documents automatic printing of the script's final expression.
- Adds details on Ollama auto-detection and new CLI flags.
- Documents the `/logout` command and updated tool list.
A fetch() deferred behind a parser-blocking script keeps a DeferredContext
in the DeferringLayer whose forward.ctx points at the Fetch struct, which
lives in a page/session arena. If the transfer completes while deferred,
it is deinited and unlinked from the frame owner, so abortTransfers ->
abortOwner can't reach the now-orphaned context. It lingers in the active
list, and when the page is torn down its Fetch arena is freed; a later
flushFrame (e.g. the next page's parser-blocking script popping) replays
the buffered header callback into the freed Fetch -> use-after-free.
Add DeferringLayer.cancelFrame to drop these orphaned (terminal) contexts
during Frame.abortTransfers. Non-terminal contexts still have a live
transfer that cleans them up through its own callback path, so they are
left alone.