- Map common key shorthand aliases to canonical KeyboardEvent keys.
- Trigger implicit form submission when pressing Enter on inputs.
- Add CSS selector support to the press tool.
Unifies printInfo/printInfoFmt and printError/printErrorFmt into
single functions accepting format arguments. Adds printDimmed for
dimmed output and supports highlighting quoted slash arguments.
- Group `/help` output into Browser, LLM, and Meta commands.
- Only show LLM commands in help if an LLM client is configured.
- Centralize the check for commands requiring an LLM in the REPL loop.
- Add descriptions to meta and LLM commands.
Replaces `printActionResult` and `printToolResult` with a single
`printToolOutcome` function. This unifies the output path and adds
red/green color coding for tool failures and successes.
When a selector times out without matching, the outcome is the same as
/hover or /click against a missing node. Returning InternalError instead
gave inconsistent feedback to the agent.
Map error.Timeout to NodeNotFound and leave the catch-all log +
InternalError for genuinely unexpected errors. Tighten the existing
MCP - waitForSelector: timeout test to pin the specific error name.
When an action triggers a navigation that swaps the root frame, the
previous page is torn down, leaving dangling DOMNode pointers in the
registry.
Reset the registry in `finalizeAction` if the frame changes to prevent
subsequent actions from dereferencing freed memory.
- Add `/.lp-history` to `.gitignore`.
- Make `SlashCommand.MetaCommand.Tag` private.
- Simplify loop in `tools.zig` using `while ... else`.
- Use `trimStart` instead of `trim` in `Schema.splitNameRest`.
- Merge `formatHealReplacement` and `formatHealReplacementLines` using
a new `HealBody` union.
- Move `interactiveTty` and `promptNumberedChoice` to `Terminal.zig`.
- Relocate and consolidate tests for `canHeal` and `isRecorded`.
- Make internal `Schema` functions private.
Page.navigate("about:blank") (and blob:) issued against a non-blank tab
routed through Session.initiateRootNavigation, which always allocated a
pending Page. A pending Page is promoted to active only by
frameHeaderDoneCallback when HTTP response headers arrive — but synthetic
navigations ZIGFLAGS= make no HTTP request, so the pending Page was never committed
and the previous document stayed active (window.location.href, document.URL
and Page.getFrameTree all kept reporting the old page).
Route synthetic URLs through the existing immediate-swap path
(replaceRootImmediate) from initiateRootNavigation, mirroring what
processRootQueuedNavigation already does for JS-initiated synthetic
navigations. replaceRootImmediate now takes (frame_id, url, opts) so both
call sites share it.
Fixes#2363
The prebuilt archive already lives at .lp-cache/prebuilt-v8/<version>.a;
the v8/libc_v8.a symlink was redundant indirection. build.zig has no
implicit lookup, so the Makefile passes -Dprebuilt_v8_path explicitly
anyway. Point it straight at the cached file, dropping the symlink step,
the v8/ dir, and its .gitignore entry. Keep the version-keyed filename so
bumping the V8 pin fetches a new file instead of clobbering.
- Replace `Action` enum with `Tool` enum using exhaustive switches
- Extract `ScriptIterator` to `Iterator.zig`
- Refactor `schema.zig` into `Schema.zig`
- Move string substitution logic into `tools.zig`
- Clean up `SlashCommand.zig` to only handle REPL meta-commands
Calculate the exact size needed for hint slots in schema.zig to avoid
overallocating. Also inline the single-use helper isDefaultTrueBool in
command.zig.
- Allow recording commands with backendNodeId if they also have a
selector, stripping backendNodeId during formatting.
- Point UnterminatedQuote errors to the opening line instead of EOF.
- Fix buildHints allocation when fields is empty but required is not.
- Update docs to clarify positional argument rules.
Tool calls with null arguments are now only considered recorded if the
tool schema has no required fields. This prevents generating invalid,
unreplayable commands for tools like `goto` or `fill`.
While both Window and WorkerGlobalState expose the same "Performance" object,
some getters are window specific (e.g. eventCounts). I thought the same object
would always have the same shape and, when not possible, they'd be different
types (e.g. Location vs WorkerLocation). But that isn't always the case. So
.exposed = .window (or .worker, defaulting to .both) can not be defined on the
bridge mapping.
- Initialize tools once globally instead of allocating per-agent.
- Refactor meta commands to use an enum for cleaner dispatch.
- Remove unused `findSchemaCanonical` and simplify command parsing.