Add --stdin flag for eval command (#348)
Adds --stdin flag to read JavaScript from stdin, enabling heredoc usage for multiline scripts without shell escaping issues.
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"agent-browser": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Add --stdin flag for eval command to read JavaScript from stdin, enabling heredoc usage for multiline scripts
|
||||||
@@ -77,7 +77,7 @@ agent-browser upload <sel> <files> # Upload files
|
|||||||
agent-browser screenshot [path] # Take screenshot (--full for full page, saves to a temporary directory if no path)
|
agent-browser screenshot [path] # Take screenshot (--full for full page, saves to a temporary directory if no path)
|
||||||
agent-browser pdf <path> # Save as PDF
|
agent-browser pdf <path> # Save as PDF
|
||||||
agent-browser snapshot # Accessibility tree with refs (best for AI)
|
agent-browser snapshot # Accessibility tree with refs (best for AI)
|
||||||
agent-browser eval <js> # Run JavaScript
|
agent-browser eval <js> # Run JavaScript (-b for base64, --stdin for piped input)
|
||||||
agent-browser connect <port> # Connect to browser via CDP
|
agent-browser connect <port> # Connect to browser via CDP
|
||||||
agent-browser close # Close browser (aliases: quit, exit)
|
agent-browser close # Close browser (aliases: quit, exit)
|
||||||
```
|
```
|
||||||
|
|||||||
+28
-14
@@ -1,5 +1,6 @@
|
|||||||
use base64::{engine::general_purpose::STANDARD, Engine};
|
use base64::{engine::general_purpose::STANDARD, Engine};
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
|
use std::io::{self, BufRead};
|
||||||
|
|
||||||
use crate::flags::Flags;
|
use crate::flags::Flags;
|
||||||
|
|
||||||
@@ -419,24 +420,37 @@ pub fn parse_command(args: &[String], flags: &Flags) -> Result<Value, ParseError
|
|||||||
|
|
||||||
// === Eval ===
|
// === Eval ===
|
||||||
"eval" => {
|
"eval" => {
|
||||||
let (is_base64, script_parts): (bool, &[&str]) =
|
// Check for flags: -b/--base64 or --stdin
|
||||||
|
let (is_base64, is_stdin, script_parts): (bool, bool, &[&str]) =
|
||||||
if rest.first() == Some(&"-b") || rest.first() == Some(&"--base64") {
|
if rest.first() == Some(&"-b") || rest.first() == Some(&"--base64") {
|
||||||
(true, &rest[1..])
|
(true, false, &rest[1..])
|
||||||
|
} else if rest.first() == Some(&"--stdin") {
|
||||||
|
(false, true, &rest[1..])
|
||||||
} else {
|
} else {
|
||||||
(false, rest.as_slice())
|
(false, false, rest.as_slice())
|
||||||
};
|
};
|
||||||
let raw_script = script_parts.join(" ");
|
|
||||||
let script = if is_base64 {
|
let script = if is_stdin {
|
||||||
let decoded = STANDARD.decode(&raw_script).map_err(|_| ParseError::InvalidValue {
|
// Read script from stdin
|
||||||
message: "Invalid base64 encoding".to_string(),
|
let stdin = io::stdin();
|
||||||
usage: "eval -b <base64-encoded-script>",
|
let lines: Vec<String> = stdin.lock().lines()
|
||||||
})?;
|
.map(|l| l.unwrap_or_default())
|
||||||
String::from_utf8(decoded).map_err(|_| ParseError::InvalidValue {
|
.collect();
|
||||||
message: "Base64 decoded to invalid UTF-8".to_string(),
|
lines.join("\n")
|
||||||
usage: "eval -b <base64-encoded-script>",
|
|
||||||
})?
|
|
||||||
} else {
|
} else {
|
||||||
raw_script
|
let raw_script = script_parts.join(" ");
|
||||||
|
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 }))
|
Ok(json!({ "id": id, "action": "evaluate", "script": script }))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -885,6 +885,7 @@ Executes JavaScript code in the browser context and returns the result.
|
|||||||
|
|
||||||
Options:
|
Options:
|
||||||
-b, --base64 Decode script from base64 (avoids shell escaping issues)
|
-b, --base64 Decode script from base64 (avoids shell escaping issues)
|
||||||
|
--stdin Read script from stdin (useful for heredocs/multiline)
|
||||||
|
|
||||||
Global Options:
|
Global Options:
|
||||||
--json Output as JSON
|
--json Output as JSON
|
||||||
@@ -895,6 +896,12 @@ Examples:
|
|||||||
agent-browser eval "window.location.href"
|
agent-browser eval "window.location.href"
|
||||||
agent-browser eval "document.querySelectorAll('a').length"
|
agent-browser eval "document.querySelectorAll('a').length"
|
||||||
agent-browser eval -b "ZG9jdW1lbnQudGl0bGU="
|
agent-browser eval -b "ZG9jdW1lbnQudGl0bGU="
|
||||||
|
|
||||||
|
# Read from stdin with heredoc
|
||||||
|
cat <<'EOF' | agent-browser eval --stdin
|
||||||
|
const links = document.querySelectorAll('a');
|
||||||
|
links.length;
|
||||||
|
EOF
|
||||||
"##
|
"##
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -189,14 +189,21 @@ agent-browser dialog dismiss # Dismiss dialog
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
agent-browser eval "document.title" # Simple expressions only
|
agent-browser eval "document.title" # Simple expressions only
|
||||||
agent-browser eval -b "<base64>" # Any JavaScript (recommended)
|
agent-browser eval -b "<base64>" # Any JavaScript (base64 encoded)
|
||||||
|
agent-browser eval --stdin # Read script from stdin
|
||||||
```
|
```
|
||||||
|
|
||||||
Use `-b`/`--base64` for reliable execution. Shell escaping with nested quotes and special characters is error-prone.
|
Use `-b`/`--base64` or `--stdin` for reliable execution. Shell escaping with nested quotes and special characters is error-prone.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Base64 encode your script, then:
|
# Base64 encode your script, then:
|
||||||
agent-browser eval -b "ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW3NyYyo9Il9uZXh0Il0nKQ=="
|
agent-browser eval -b "ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW3NyYyo9Il9uZXh0Il0nKQ=="
|
||||||
|
|
||||||
|
# Or use stdin with heredoc for multiline scripts:
|
||||||
|
cat <<'EOF' | agent-browser eval --stdin
|
||||||
|
const links = document.querySelectorAll('a');
|
||||||
|
Array.from(links).map(a => a.href);
|
||||||
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
## State Management
|
## State Management
|
||||||
|
|||||||
Reference in New Issue
Block a user