Allows fetching sub-pages per row and resolving nested fields against
them. Supports string templates with sibling placeholders (e.g., `{id}`)
and element-specs. Updates the JS walker to be async.
Update agent docs and tool descriptions to note that objects and
arrays are automatically serialized to JSON, making manual
`JSON.stringify` calls unnecessary.
Falls back to compiling the script inside an async IIFE if the initial
block-scoped compilation fails. This enables top-level await and return
statements directly in the eval tool.
Make the numbered agent choice prompt interactive on TTYs: Up/Down
moves the selected row, Enter confirms it, and numeric input still works as before.
Keep the line-based numbered prompt as the non-interactive fallback, restore
terminal settings after the raw-mode picker exits, and render raw-mode output
with CRLF so menu rows stay aligned. Dim the picker hint text to match existing
terminal command hints.
Implements Levenshtein distance-based suggestions for unknown slash
commands. If a typo is within two edits of a valid command, the
terminal suggests it with "Did you mean ...?".
Enables `load_external_stylesheets` when an LLM client is active,
as LLM drivers reason about visibility and computed styles.
Updates the help documentation to reflect this change.
Replaces the fragile `firstSentence` parser with an explicit `summary`
field on tool definitions. Also standardizes user-facing REPL
terminology to "command" instead of "slash command" or "tool".
* agent: add a /model command to chnage current model
And remove the pick-model CLI option
* agent: add /provider to change the current provider
* agent: extract requireLlmNoArg helper
* agent: simplify provider detection
* repl: add tab completion for /model and /provider
Changes `/model` and `/provider` to accept an optional name argument
instead of prompting with a numbered list. Bare commands now print the
current selection, while Tab dynamically completes candidates. Model
lists are fetched and cached to prevent redundant network requests.
* agent: remember last selected provider and model
Persists the last selected AI provider and model in a local
`.lp-agent` file and resumes it on startup. Removes the
interactive provider picker in favor of deterministic auto-detection.
* agent: simplify requireLlm and model resolution
Changes `requireLlm` to return a boolean instead of credentials, and
cleans up the model initialization logic to use `resolved` directly.
Also removes unused user errors.
---------
Co-authored-by: Adrià Arrufat <adria.arrufat@gmail.com>
With the new CookieStore, the session must be freed before the notification is.
This is how it works in CDP, but in fetch, we were pretty lazy about it. This
caused the notification to be freed first, and then the cookiestore to try to
unregister: UAF.
* tools: add session-scoped bridge store
Exposes `globalThis.lp` to `/eval` calls, allowing state to persist
across evaluations and page navigations. Adds a `save` parameter to
both `/eval` and `/extract` to store results in the bridge.
* browser: await promises in eval and support inline args
- Await JS Promises in `eval` tool with a 30s timeout
- Support inline arguments in multi-line slash commands
- Silence output on successful `save=`
- Add `limit` option to extract schema walker
* eval: return empty text for undefined async IIFE
* extract: support limit on simple string arrays
Treats `["<sel>"]` as sugar for `[{"selector": "<sel>"}]` in the schema
walker. This enables the `"limit"` option on simple string arrays.
Also updates agent documentation to cover cross-call state with `lp.*`.
* refactor: optimize bridge store and schema lookup
- Introduce `bridgeStorePut` to skip redundant JSON validation for
trusted stringified values in `bridgeSync`.
- Store the schema pointer in `BlockOpener` to avoid re-parsing and
looking up the schema in `Iterator.next`.
- Clean up error handling and optional unwrapping in `execEval`.
- Remove unused parameters from save helper functions.
- Inline and simplify save path duplication and file writing.
- Clean up optional unwrapping for the recorder.
Add a REPL-only `/save [filename.lp]` command that persists the current
interactive session as PandaScript without requiring the user to start the
agent with `-i <script>`. The command records the same replayable actions as
the existing script recorder, but keeps them in memory until the user chooses
to save.
Functional behavior:
- During a REPL session, record replayable browser actions into an in-memory
script buffer.
- Manual slash commands are recorded through the same PandaScript formatting
and filtering rules used by file recording.
- Natural-language turns record their prompt as a `# ...` comment only when
the LLM turn produces at least one successful replayable tool call.
- Failed LLM tool calls are skipped, and repeated successful `/extract` calls
keep only the last successful extract, matching the existing recorder logic.
- `/save filename.lp` writes the current in-memory recording to that file.
- Bare `/save` creates a random `session-<hex>.lp` file on first save.
- If the first save targets an existing file, prompt with the existing numbered
TTY picker and ask whether to replace or append.
- After the first successful save, the REPL session is locked to that filename:
later `/save` or `/save same-file.lp` appends to the same file without
prompting, while `/save other-file.lp` is rejected.
- After each successful save, reset the in-memory recorder so future saves only
append actions entered since the previous save.
- On any `/save` error or cancellation, keep the in-memory recorder intact so
the user can retry without losing captured actions.
- Restrict `/save` filenames to local file names, not paths, to keep behavior
scoped to the current directory.
Code changes:
- Add `Recorder.Memory`, an in-memory recorder that shares the existing
`Command.isRecorded`, `Command.format`, comment formatting, and `LP_*`
reverse-substitution behavior with file recording.
- Add `Recorder.Memory.reset()` so `/save` can clear only successfully saved
deltas.
- Add `/save` to the REPL meta command table and help/completion surface.
- Add `save_buffer` and `save_path` state to `Agent`.
- Feed manual REPL tool calls into `save_buffer` alongside the existing optional
file recorder.
- Extend LLM turn recording with a `capture_for_save` flag so natural-language
REPL turns can be captured without affecting non-REPL script/self-heal paths.
- Implement `/save` handling in `Agent`:
- parse and validate the optional filename,
- choose replace/append for existing first-save targets,
- remember the first successful save path,
- enforce the single-destination rule for the rest of the session,
- append later deltas by default,
- commit remembered path state only after a successful file write.
- Add focused coverage for the memory recorder’s filtering and reset behavior.
If a synthetic url (blob URL) causes a navigation event, the frame abort will
deinit the transfer, causing the `defer transfer.deinit()` atop Synthetic.run
from firing. Flag the transfer as .completing to prevent this from happening.
This mimics what non-synthetic urls do.
Adds a pretty simplistic Notification WebAPI. Also adds a dummy drawImage to
CanvasRenderingContext2D.
Trying to improve how we're seen by https://bot.sannysoft.com/