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.
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.
- 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
Replaces the string `name` in `ToolCall` with `action: browser_tools.Action`.
This avoids repeated string-to-enum parsing and simplifies schema lookups.
Also updates `zenai` dependency to use its JSON duplication helper.
- Remove `input_schema_raw` from `SchemaInfo` and use `parameters` directly
- Simplify JSON field extraction in `Verifier` to avoid `parseArgs`
- Refactor REPL command splitting and environment substitution
- Clean up and condense comments across the codebase
- Add support for triple-quoted strings (''' and """) in the tokenizer
and quote stripper.
- Avoid allocations in `stripQuotes` by returning slices.
- Optimize schema lookups using O(1) enum-based canonical resolution.
- Skip env var substitution if "$LP_" is not present in the string.
Unifies PandaScript syntax by replacing uppercase keywords with slash
commands (e.g., `/goto`, `/click`, `/fill`). Refactors the `Command`
representation to use a generic tool call structure backed by schemas.
BREAKING CHANGE: Uppercase PandaScript keywords (GOTO, CLICK, TYPE, etc.)
are no longer supported. All scripts must use slash commands.
Update `Recorder.init` to accept a `std.fs.Dir` and relative path,
decoupling it from the current working directory.
Also add a persistent arena allocator to `Recorder` to reuse
allocations when scrubbing environment variables on each write.
Renames `Command.zig` to `command.zig` and moves associated functions
like `parse`, `toToolCall`, and `canHeal` directly into the `Command`
union. This simplifies usage from `Command.Command` to just `Command`.
- Replace `Self` with `Recorder` and `Verifier` for improved clarity.
- Add `Spinner.isEnabled()` to encapsulate atomic state access.
- Shorten and refine various comments across the codebase.
- Make `VerifyResult.failed` reason non-optional with an OOM fallback.
- Use `ElementProperty` enum for safer JS property injection.
- Ensure `Recorder` disables on all errors to prevent silent data loss.
- Add `CHECK` command round-trip test.
- Prevent UB in `applyReplacements` with pointer assertions.
- Reorder `writeAtomic` to build content before writing backup.
- Strip trailing `\r` in `ScriptIterator` for CRLF compatibility.
- Use shorter representation for `SCROLL` commands.
- Filter redundant `extract` calls in recordings to reduce noise.
- Scrub literal `LP_*` secrets from recorded commands for portability.
- Throw a descriptive error in `extract` when no selectors match.
- Update tool descriptions and guidance to favor a `tree` ->
`nodeDetails` -> `extract` workflow for more robust selectors.
- Replace `unreachable` with explicit error returns in Agent and Executor.
- Add `EvalResult.err` helper in `tools.zig` to simplify error paths.
- Improve error propagation in `SlashCommand` and `Recorder`.
- Rename `Self` to `Agent` for better clarity in function signatures.