Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
733e09a
Fix broken link in README.md
gthb Feb 17, 2026
67a831f
Fix `rodney start --show` flag parsing bug
jacobb Feb 18, 2026
2d23ae0
Add installation instructions
tavva Feb 18, 2026
a2bb3d7
Add stdin support for `rodney js`
slaskis Feb 18, 2026
8a018f9
Add stdin support for `rodney assert`
slaskis Feb 19, 2026
76e1a06
Fix usage string to show -k shorthand, matching help.txt
jacobb Feb 19, 2026
8595de8
Add --fake-media flag to prevent crashes on pages that request microp…
EdwardSalkeld Feb 23, 2026
072bd70
Document --fake-media flag in README
EdwardSalkeld Feb 24, 2026
85dc389
Add `rodney viewport` command and `--viewport` flag for mobile emulation
johnwards Feb 28, 2026
7f34538
Make screenshot respect active viewport set via `rodney viewport`
johnwards Feb 28, 2026
3c5fc60
Add `rodney discover` command for listing data-testid elements
jstockdi Mar 9, 2026
519dfaa
Add `rodney logs` command for persistent console log capture (#1)
jstockdi Mar 9, 2026
dfc3c77
Merge branch 'pr/22'
jstockdi Mar 9, 2026
2cf6f03
Merge branch 'pr/25'
jstockdi Mar 9, 2026
31ee839
Merge branch 'pr/31'
jstockdi Mar 9, 2026
f10a2c3
Merge branch 'pr/24'
jstockdi Mar 9, 2026
85d792f
Merge branch 'pr/38'
jstockdi Mar 9, 2026
534f36f
Merge branch 'pr/40'
jstockdi Mar 9, 2026
4bb1390
Add contextual page inspection on element failures
jstockdi Apr 3, 2026
2e1af7b
Add composable check command for batched assertions
jstockdi Apr 3, 2026
d4fd2fc
Add accessibility selectors (--role, --name) to action commands
jstockdi Apr 3, 2026
b1e18e5
Add --forms, --links, --interactive modes to discover command
jstockdi Apr 3, 2026
06fe848
Add --stealth flag to remove automation fingerprints
jstockdi Apr 3, 2026
80befa3
Add --text and --gone options to wait command
jstockdi Apr 3, 2026
6d8cc99
Add contextual error suggestions for common failures
jstockdi Apr 3, 2026
b545521
Add repeated failure detection via state ring buffer
jstockdi Apr 3, 2026
ffb1bf0
Merge branch 'worktree-agent-a2665c2f'
jstockdi Apr 3, 2026
2a03652
Merge branch 'worktree-agent-a36c5b75'
jstockdi Apr 3, 2026
f4a9b13
Merge branch 'worktree-agent-a5d63aff'
jstockdi Apr 3, 2026
c8a5ef9
Merge branch 'worktree-agent-a81c872f'
jstockdi Apr 3, 2026
37f1268
Merge branch 'worktree-agent-a95b28a2'
jstockdi Apr 3, 2026
2f96eeb
Merge branch 'worktree-agent-a1d82f1f'
jstockdi Apr 3, 2026
965bb8f
Merge branch 'worktree-agent-ae89aae9'
jstockdi Apr 3, 2026
8bb96a8
Add upstream comparison script and README section
jstockdi Apr 3, 2026
8325836
Merge remote-tracking branch 'simonw/main'
jstockdi Apr 3, 2026
781bd1c
Use system-installed Chrome before falling back to auto-download (#2)
jstockdi Apr 9, 2026
ec21551
Fix Chrome launch crashes on macOS desktop
jstockdi Apr 13, 2026
7beaabe
Add dependency-review workflow (scaffolded by repocat)
jstockdi May 6, 2026
1e039ad
Pin GitHub Actions to commit SHAs (#4)
jstockdi May 6, 2026
1352acb
Add SECURITY.md (#3)
jstockdi May 6, 2026
73e9c89
Add CHANGELOG.md (#5)
jstockdi May 6, 2026
0ada274
Drop PyPI publish path and rebrand to Battle-Creek-LLC (#6)
jstockdi May 6, 2026
3c2c02b
Add Semgrep code-scanning workflow (scaffolded by repocat)
jstockdi May 23, 2026
53e03bd
Suppress false-positive Semgrep dangerous-exec-command findings (#7)
jstockdi May 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Dependency Review

on:
pull_request:

permissions:
contents: read

jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48
53 changes: 5 additions & 48 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ jobs:
# goarch: arm64

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Set up Go
uses: actions/setup-go@v6
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
with:
go-version: '1.24.x'
- name: Build binaries
Expand Down Expand Up @@ -76,7 +76,7 @@ jobs:
dist_bin="dist/rodney-linux-amd64/rodney"
"$dist_bin" --version | grep -Fx "$version"
- name: Upload build artifacts
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: rodney-${{ matrix.goos }}-${{ matrix.goarch }}
path: |
Expand All @@ -88,56 +88,13 @@ jobs:
needs: build-binaries
steps:
- name: Download build artifacts
uses: actions/download-artifact@v6
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
path: dist
merge-multiple: true
- name: Upload release assets
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2
with:
files: dist/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

build-wheels:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: '1.24.x'
- name: Install uv
uses: astral-sh/setup-uv@v6
- name: Build wheels
run: |
version="${GITHUB_REF_NAME#v}"
uvx go-to-wheel . \
--readme README.md \
--description "Chrome automation from the command line" \
--author 'Simon Willison' \
--license Apache-2.0 \
--url https://github.com/simonw/rodney \
--set-version-var main.version \
--version "$version"
- name: Store the distribution packages
uses: actions/upload-artifact@v6
with:
name: python-packages
path: dist/

publish:
name: Publish to PyPI
runs-on: ubuntu-latest
needs: [build-wheels]
environment: release
permissions:
id-token: write
steps:
- name: Download distribution packages
uses: actions/download-artifact@v6
with:
name: python-packages
path: dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
24 changes: 24 additions & 0 deletions .github/workflows/semgrep.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Semgrep

on:
pull_request:
push:
branches: [main]
schedule:
- cron: "0 6 * * 1"

permissions:
contents: read
security-events: write

jobs:
semgrep:
name: semgrep
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- run: pipx run semgrep scan --config p/default --config p/secrets --sarif --output semgrep.sarif
- uses: github/codeql-action/upload-sarif@84498526a009a99c875e83ef4821a8ba52de7c22
if: always()
with:
sarif_file: semgrep.sarif
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ jobs:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Set up Go
uses: actions/setup-go@v6
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
with:
go-version: '1.24'
- name: Build
Expand Down
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.1.0] - 2026-05-06

Initial release of the Battle-Creek-LLC fork of [simonw/rodney](https://github.com/simonw/rodney).

### Added
- Forked upstream `simonw/rodney` and merged through commit `8325836`.
- Use system-installed Chrome before falling back to auto-download (#2).
- Crash-loop detection via state ring buffer.
- Contextual error suggestions for common failures.
- `--text` and `--gone` options on the `wait` command.
- `--stealth` flag to remove automation fingerprints.
- `--forms`, `--links`, `--interactive` modes on `discover`.
- Accessibility selectors (`--role`, `--name`) on action commands.
- Composable `check` command for batched assertions.
- Upstream-comparison helper script and README section.
- Repository-policy baseline via repocat (branch protection, signed commits,
secret scanning, Dependabot, dependency-review workflow, pinned action SHAs).

### Fixed
- Chrome launch crashes on macOS desktop.

[Unreleased]: https://github.com/Battle-Creek-LLC/rodney/compare/v0.1.0...HEAD
[0.1.0]: https://github.com/Battle-Creek-LLC/rodney/releases/tag/v0.1.0
99 changes: 81 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,35 @@
# Rodney: Chrome automation from the command line

[![PyPI](https://img.shields.io/pypi/v/rodney.svg)](https://pypi.org/project/rodney/)
[![Changelog](https://img.shields.io/github/v/release/simonw/rodney?include_prereleases&label=changelog)](https://github.com/simonw/rodney/releases)
[![Tests](https://github.com/simonw/rodney/actions/workflows/test.yml/badge.svg)](https://github.com/simonw/rodney/actions/workflows/test.yml)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/simonw/rodney/blob/main/LICENSE)
[![Changelog](https://img.shields.io/github/v/release/Battle-Creek-LLC/rodney?include_prereleases&label=changelog)](https://github.com/Battle-Creek-LLC/rodney/releases)
[![Tests](https://github.com/Battle-Creek-LLC/rodney/actions/workflows/test.yml/badge.svg)](https://github.com/Battle-Creek-LLC/rodney/actions/workflows/test.yml)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/Battle-Creek-LLC/rodney/blob/main/LICENSE)

A Go CLI tool that drives a persistent headless Chrome instance using the [rod](https://github.com/go-rod/rod) browser automation library. Each command connects to the same long-running Chrome process, making it easy to script multi-step browser interactions from shell scripts or interactive use.

This is the Battle-Creek-LLC fork of [simonw/rodney](https://github.com/simonw/rodney).

## Installation

Install the Go binary directly:
```bash
go install github.com/battle-creek-llc/rodney@latest
```
Or run it without installation:
```bash
go run github.com/battle-creek-llc/rodney@latest --help
```
Compiled binaries are available [on the releases page](https://github.com/Battle-Creek-LLC/rodney/releases). On macOS you may need to [follow these extra steps](https://support.apple.com/en-us/102445) to use those.

## Building

```bash
go build -o rodney .
```

Requires:
- Go 1.21+
- Google Chrome or Chromium installed (or set `ROD_CHROME_BIN=/path/to/chrome`)

## Architecture

```
Expand All @@ -26,16 +49,6 @@ rodney stop → connects and shuts down Chrome, cleans up state

Each CLI invocation is a short-lived process. Chrome runs independently and tabs persist between commands.

## Building

```bash
go build -o rodney .
```

Requires:
- Go 1.21+
- Google Chrome or Chromium installed (or set `ROD_CHROME_BIN=/path/to/chrome`)

## Usage

### Start/stop the browser
Expand All @@ -44,6 +57,8 @@ Requires:
rodney start # Launch headless Chrome
rodney start --show # Launch with visible browser window
rodney start --insecure # Launch with TLS errors ignored (-k shorthand)
rodney start --fake-media # Launch with fake media devices (avoids getUserMedia crashes)
rodney start --viewport 375x812 --mobile --scale 2 # Start with mobile viewport
rodney connect host:9222 # Connect to existing Chrome on remote debug port
rodney status # Show browser info and active page
rodney stop # Shut down Chrome
Expand Down Expand Up @@ -73,6 +88,24 @@ rodney attr "a#link" href # Print attribute value
rodney pdf output.pdf # Save page as PDF
```

### Console logs

```bash
rodney logs # Print all buffered console logs and exit
rodney logs -n 5 # Print last 5 buffered log entries
rodney logs -f # Print buffered logs, then stream new ones (Ctrl+C to stop)
rodney logs -f -n 5 # Print last 5 buffered logs, then stream new ones
rodney logs --json # JSON output (one object per line)
```

Text output format: `[level] message` (e.g. `[error] Uncaught TypeError: ...`).

JSON output format (one object per line):
```json
{"level":"info","source":"javascript","text":"Page initialized","timestamp":"2024-01-01T12:00:00.123Z"}
{"level":"error","source":"javascript","text":"Uncaught TypeError: ...","timestamp":"2024-01-01T12:00:00.456Z","url":"https://example.com/app.js","line":42}
```

### Run JavaScript

```bash
Expand All @@ -81,10 +114,15 @@ rodney js "1 + 2" # Math
rodney js 'document.querySelector("h1").textContent' # DOM queries
rodney js '[1,2,3].map(x => x * 2)' # Returns pretty-printed JSON
rodney js 'document.querySelectorAll("a").length' # Count elements
echo 'document.title' | rodney js # Read expression from stdin
cat script.js | rodney js # Execute a JS file via stdin
rodney js - # Read from stdin explicitly
```

The expression is automatically wrapped in `() => { return (expr); }`.

When no argument is given and stdin is piped, the expression is read from stdin. Pass `-` as the argument to read from stdin explicitly.

### Interact with elements

```bash
Expand Down Expand Up @@ -116,10 +154,22 @@ rodney sleep 2.5 # Sleep for N seconds
```bash
rodney screenshot # Save as screenshot.png
rodney screenshot page.png # Save to specific file
rodney screenshot -w 1280 -h 720 out.png # Set viewport width/height
rodney screenshot -w 1280 -h 720 out.png # Override viewport width/height
rodney screenshot-el ".chart" chart.png # Screenshot specific element
```

When a viewport has been set via `rodney viewport`, screenshots use that viewport by default. Pass `-w`/`-h` to override.

### Viewport / mobile emulation

```bash
rodney viewport 375 812 # iPhone-sized viewport
rodney viewport 375 812 --mobile # With mobile emulation (viewport meta, etc.)
rodney viewport 375 812 --mobile --scale 3 # Retina-class device pixel ratio
rodney viewport 1280 720 # Desktop viewport
rodney viewport --reset # Reset to browser default
```

### Manage tabs

```bash
Expand Down Expand Up @@ -381,7 +431,7 @@ In environments with authenticated HTTP proxies (e.g., `HTTPS_PROXY=http://user:

This is necessary because Chrome cannot natively authenticate to proxies during HTTPS tunnel (CONNECT) establishment. The local proxy runs as a background process and is automatically cleaned up by `rodney stop`.

See [claude-code-chrome-proxy.md](claude-code-chrome-proxy.md) for detailed technical notes.
See [notes/claude-chrome-proxy](notes/claude-chrome-proxy) for detailed technical notes.

## How it works

Expand All @@ -403,7 +453,7 @@ The tool uses the [rod](https://github.com/go-rod/rod) Go library which communic

| Command | Arguments | Description |
|---|---|---|
| `start` | `[--show] [--insecure\|-k]` | Launch Chrome (headless by default, `--show` for visible) |
| `start` | `[--show] [--insecure\|-k] [--logs] [--fake-media] [--viewport WxH] [--mobile] [--scale N]` | Launch Chrome (headless by default, `--show` for visible) |
| `connect` | `<host:port>` | Connect to existing Chrome on remote debug port |
| `stop` | | Shut down Chrome |
| `status` | | Show browser status |
Expand All @@ -418,7 +468,7 @@ The tool uses the [rod](https://github.com/go-rod/rod) Go library which communic
| `text` | `<selector>` | Print element text content |
| `attr` | `<selector> <name>` | Print attribute value |
| `pdf` | `[file]` | Save page as PDF |
| `js` | `<expression>` | Evaluate JavaScript |
| `js` | `<expression>\|-` | Evaluate JavaScript (`-` or no arg reads from stdin) |
| `click` | `<selector>` | Click element |
| `input` | `<selector> <text>` | Type into input |
| `clear` | `<selector>` | Clear input |
Expand All @@ -435,6 +485,8 @@ The tool uses the [rod](https://github.com/go-rod/rod) Go library which communic
| `sleep` | `<seconds>` | Sleep N seconds |
| `screenshot` | `[-w N] [-h N] [file]` | Page screenshot (optional viewport size) |
| `screenshot-el` | `<selector> [file]` | Element screenshot |
| `viewport` | `<width> <height> [--scale N] [--mobile]` | Set browser viewport size |
| `viewport` | `--reset` | Reset viewport to browser default |
| `pages` | | List tabs |
| `page` | `<index>` | Switch tab |
| `newpage` | `[url]` | Open new tab |
Expand All @@ -443,6 +495,7 @@ The tool uses the [rod](https://github.com/go-rod/rod) Go library which communic
| `count` | `<selector>` | Count matching elements |
| `visible` | `<selector>` | Check element visible (exit 1 if not) |
| `assert` | `<expr> [expected] [-m msg]` | Assert JS expression is truthy or equals expected (exit 1 if not) |
| `logs` | `[-f] [-n N] [--json]` | Print console logs (snapshot or stream with `-f`) |
| `ax-tree` | `[--depth N] [--json]` | Dump accessibility tree |
| `ax-find` | `[--name N] [--role R] [--json]` | Find accessible nodes |
| `ax-node` | `<selector> [--json]` | Show element accessibility info |
Expand All @@ -455,3 +508,13 @@ The tool uses the [rod](https://github.com/go-rod/rod) Go library which communic
| `--global` | Use global session (`~/.rodney/`) |
| `--version` | Print version and exit |
| `--help`, `-h`, `help` | Show help message |

## Comparing with upstream

This fork adds features on top of [simonw/rodney](https://github.com/simonw/rodney). To see how this fork diverges from upstream:

```bash
./scripts/compare-upstream.sh
```

The script fetches both remotes, shows commit divergence in each direction, and prints a file-level diff summary. If upstream has commits this fork is missing, it will suggest the merge command.
16 changes: 16 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Security Policy

## Reporting a Vulnerability

Please report security vulnerabilities privately via GitHub's
[private vulnerability reporting](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability)
feature on this repository's **Security** tab.

We aim to acknowledge reports within 5 business days and provide an
initial assessment within 10 business days. Please do not file public
issues for security-sensitive reports.

## Supported Versions

This project follows a rolling-release model — only the current `main`
branch is supported.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/simonw/rodney
module github.com/battle-creek-llc/rodney

go 1.24.7

Expand Down
Loading