Add base64 input for eval command (#340)

* Add base64 input for eval command

Adds -b/--base64 flag to decode script from base64, avoiding shell escaping issues for AI agents.

* Document base64 eval in SKILL.md
This commit is contained in:
Chris Tate
2026-02-02 18:52:43 -06:00
committed by GitHub
parent bdf674a27e
commit 9c45f82193
5 changed files with 92 additions and 3 deletions
+7
View File
@@ -6,6 +6,7 @@ version = 4
name = "agent-browser"
version = "0.8.7"
dependencies = [
"base64",
"dirs",
"libc",
"serde",
@@ -13,6 +14,12 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bitflags"
version = "2.10.0"
+1
View File
@@ -9,6 +9,7 @@ license = "Apache-2.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
dirs = "5.0"
base64 = "0.22"
[target.'cfg(unix)'.dependencies]
libc = "0.2"
+70 -1
View File
@@ -1,3 +1,4 @@
use base64::{engine::general_purpose::STANDARD, Engine};
use serde_json::{json, Value};
use crate::flags::Flags;
@@ -417,7 +418,28 @@ pub fn parse_command(args: &[String], flags: &Flags) -> Result<Value, ParseError
}
// === Eval ===
"eval" => Ok(json!({ "id": id, "action": "evaluate", "script": rest.join(" ") })),
"eval" => {
let (is_base64, script_parts): (bool, &[&str]) =
if rest.first() == Some(&"-b") || rest.first() == Some(&"--base64") {
(true, &rest[1..])
} else {
(false, rest.as_slice())
};
let raw_script = script_parts.join(" ");
let script = if is_base64 {
let decoded = STANDARD.decode(&raw_script).map_err(|_| ParseError::InvalidValue {
message: "Invalid base64 encoding".to_string(),
usage: "eval -b <base64-encoded-script>",
})?;
String::from_utf8(decoded).map_err(|_| ParseError::InvalidValue {
message: "Base64 decoded to invalid UTF-8".to_string(),
usage: "eval -b <base64-encoded-script>",
})?
} else {
raw_script
};
Ok(json!({ "id": id, "action": "evaluate", "script": script }))
}
// === Close ===
"close" | "quit" | "exit" => Ok(json!({ "id": id, "action": "close" })),
@@ -2025,6 +2047,53 @@ mod tests {
));
}
// === Eval Tests ===
#[test]
fn test_eval_basic() {
let cmd = parse_command(&args("eval document.title"), &default_flags()).unwrap();
assert_eq!(cmd["action"], "evaluate");
assert_eq!(cmd["script"], "document.title");
}
#[test]
fn test_eval_base64_short_flag() {
// "document.title" in base64
let cmd = parse_command(&args("eval -b ZG9jdW1lbnQudGl0bGU="), &default_flags()).unwrap();
assert_eq!(cmd["action"], "evaluate");
assert_eq!(cmd["script"], "document.title");
}
#[test]
fn test_eval_base64_long_flag() {
// "document.title" in base64
let cmd =
parse_command(&args("eval --base64 ZG9jdW1lbnQudGl0bGU="), &default_flags()).unwrap();
assert_eq!(cmd["action"], "evaluate");
assert_eq!(cmd["script"], "document.title");
}
#[test]
fn test_eval_base64_with_special_chars() {
// "document.querySelector('[src*=\"_next\"]')" in base64
let cmd = parse_command(
&args("eval -b ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW3NyYyo9Il9uZXh0Il0nKQ=="),
&default_flags(),
)
.unwrap();
assert_eq!(cmd["action"], "evaluate");
assert_eq!(cmd["script"], "document.querySelector('[src*=\"_next\"]')");
}
#[test]
fn test_eval_base64_invalid() {
let result = parse_command(&args("eval -b !!!invalid!!!"), &default_flags());
assert!(result.is_err());
let err = result.unwrap_err();
assert!(matches!(err, ParseError::InvalidValue { .. }));
assert!(err.format().contains("Invalid base64"));
}
#[test]
fn test_unknown_command() {
let result = parse_command(&args("unknowncommand"), &default_flags());
+5 -1
View File
@@ -879,10 +879,13 @@ Examples:
r##"
agent-browser eval - Execute JavaScript
Usage: agent-browser eval <script>
Usage: agent-browser eval [options] <script>
Executes JavaScript code in the browser context and returns the result.
Options:
-b, --base64 Decode script from base64 (avoids shell escaping issues)
Global Options:
--json Output as JSON
--session <name> Use specific session
@@ -891,6 +894,7 @@ Examples:
agent-browser eval "document.title"
agent-browser eval "window.location.href"
agent-browser eval "document.querySelectorAll('a').length"
agent-browser eval -b "ZG9jdW1lbnQudGl0bGU="
"##
}
+9 -1
View File
@@ -214,7 +214,15 @@ agent-browser dialog dismiss # Dismiss dialog
### JavaScript
```bash
agent-browser eval "document.title" # Run JavaScript
agent-browser eval "document.title" # Simple expressions only
agent-browser eval -b "<base64>" # Any JavaScript (recommended)
```
Use `-b`/`--base64` for reliable execution. Shell escaping with nested quotes and special characters is error-prone.
```bash
# Base64 encode your script, then:
agent-browser eval -b "ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW3NyYyo9Il9uZXh0Il0nKQ=="
```
## Global options