rebrand to EJClaw, update README and browser skill
- Rename project to EJClaw, update README with verified features - Update agent-browser SKILL.md for gstack browse commands (goto, snapshot -D/-a/-C, tabs, dialogs, etc.)
This commit is contained in:
277
README.md
277
README.md
@@ -1,223 +1,105 @@
|
||||
<p align="center">
|
||||
<img src="assets/nanoclaw-logo.png" alt="NanoClaw" width="400">
|
||||
</p>
|
||||
# EJClaw
|
||||
|
||||
<p align="center">
|
||||
Dual-agent AI assistant running Claude Code + Codex as parallel services over Discord.
|
||||
</p>
|
||||
Dual-agent AI assistant (Claude Code + Codex) over Discord.
|
||||
|
||||
<p align="center">
|
||||
Based on <a href="https://github.com/qwibitai/nanoclaw">qwibitai/nanoclaw</a>
|
||||
</p>
|
||||
Forked from [qwibitai/nanoclaw](https://github.com/qwibitai/nanoclaw), heavily customized for production use.
|
||||
|
||||
## Overview
|
||||
|
||||
Two AI agents running as parallel systemd services, communicating over Discord:
|
||||
Two AI agents running as parallel systemd services on a single host:
|
||||
|
||||
- **Claude Code** — powered by Claude Agent SDK, trigger `@claude`
|
||||
- **Codex** — powered by Codex app-server (JSON-RPC), trigger `@codex`
|
||||
- **Claude Code** (`@claude`) — Anthropic Agent SDK, adaptive thinking, Opus/Sonnet
|
||||
- **Codex** (`@codex`) — OpenAI Codex app-server (JSON-RPC), GPT-5.4, xhigh reasoning
|
||||
|
||||
Each agent has its own store, data, and groups directories. Discord channels can be registered with either agent, or both (`both` agent type for shared channels).
|
||||
Both share the same codebase (`dist/index.js`), differentiated by environment variables. No containers — direct host processes for zero overhead.
|
||||
|
||||
### Key Features
|
||||
## Features
|
||||
|
||||
- **Direct host processes** — no container overhead, agents run natively
|
||||
- **Bidirectional image support** — receive images as multimodal input, send as Discord attachments
|
||||
- **Skill sync** — single source of truth (`~/.claude/skills/`), auto-synced to all sessions
|
||||
- **OAuth auto-refresh** — token lifecycle managed automatically for headless environments
|
||||
- **Priority queue** — per-group serialization, global concurrency limit, idle preemption
|
||||
- **Auto-continue** — Codex text-only turns automatically retried to enforce task execution
|
||||
- **Dual-agent architecture** — Claude Code + Codex as parallel services, shared SQLite (WAL mode)
|
||||
- **Browser automation** — [gstack browse](https://github.com/garrytan/gstack) skill, headless Chromium daemon, ~100ms/command
|
||||
- **Voice transcription** — Groq Whisper (primary) / OpenAI Whisper (fallback), shared file cache with dedup
|
||||
- **Bidirectional images** — receive Discord attachments as multimodal input, send screenshots back
|
||||
- **MCP integration** — Memento (persistent cross-session memory)
|
||||
- **Skill sync** — single source of truth, auto-synced to all agent sessions
|
||||
- **Priority queue** — per-group serialization, global concurrency limit
|
||||
- **Session persistence** — resume conversations across restarts
|
||||
- **Scheduled tasks** — cron/interval/once via MCP tool
|
||||
- **Mid-turn steering** — inject follow-up messages while agent is working (both agents)
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Discord ──► SQLite ──► GroupQueue ──┬──► Claude Agent SDK (host process)
|
||||
└──► Codex App-Server (JSON-RPC stdio)
|
||||
├── thread/start, thread/resume
|
||||
├── turn/start (streaming, multimodal)
|
||||
├── turn/steer (mid-turn injection)
|
||||
├── Auto-approval (bypass sandbox)
|
||||
└── Auto-continue (text-only turn retry)
|
||||
Discord ──► SQLite (WAL) ──► GroupQueue ──┬──► Claude Agent SDK
|
||||
└──► Codex App-Server (JSON-RPC)
|
||||
├── thread/start, thread/resume
|
||||
├── turn/start (streaming, multimodal)
|
||||
└── turn/steer (mid-turn injection)
|
||||
|
||||
Agent ──► Bash ──► agent-browser (gstack browse)
|
||||
├── goto, snapshot, click, fill
|
||||
├── screenshot, pdf, responsive
|
||||
└── persistent Chromium daemon (~100ms/cmd)
|
||||
```
|
||||
|
||||
### Directory Layout
|
||||
## Directory Layout
|
||||
|
||||
```
|
||||
nanoclaw/
|
||||
ejclaw/
|
||||
├── src/
|
||||
│ ├── index.ts # Orchestrator: state, message loop, agent invocation
|
||||
│ ├── agent-runner.ts # Spawns agent processes, manages env/sessions/skills
|
||||
│ ├── group-queue.ts # Per-group concurrency, priority queue, idle preemption
|
||||
│ ├── group-folder.ts # Group directory resolution and management
|
||||
│ ├── router.ts # Outbound message formatting and routing
|
||||
│ ├── sender-allowlist.ts # Security: sender-based access control
|
||||
│ ├── session-commands.ts # Session commands (/compact)
|
||||
│ ├── token-refresh.ts # OAuth auto-refresh + session directory sync
|
||||
│ ├── task-scheduler.ts # Scheduled tasks (cron/interval/once)
|
||||
│ ├── ipc.ts # IPC watcher and task processing
|
||||
│ ├── db.ts # SQLite operations
|
||||
│ ├── config.ts # Paths, intervals, trigger patterns
|
||||
│ ├── index.ts # Orchestrator: state, message loop, agent invocation
|
||||
│ ├── agent-runner.ts # Spawns agent processes, manages env/sessions/skills
|
||||
│ ├── group-queue.ts # Per-group concurrency, priority queue
|
||||
│ ├── router.ts # Outbound message formatting and routing
|
||||
│ ├── db.ts # SQLite operations (WAL mode, shared access)
|
||||
│ ├── config.ts # Paths, intervals, trigger patterns
|
||||
│ └── channels/
|
||||
│ ├── registry.ts # Channel self-registration system
|
||||
│ └── discord.ts # Discord: mentions, images, typing, file attachments
|
||||
│ └── discord.ts # Discord: mentions, images, typing, voice transcription
|
||||
├── runners/
|
||||
│ ├── agent-runner/ # Claude Code runner (Agent SDK, multimodal input)
|
||||
│ ├── codex-runner/ # Codex runner (app-server JSON-RPC, auto-continue)
|
||||
│ └── skills/ # Shared agent skills (browser, etc.)
|
||||
├── store/ # Claude Code service DB
|
||||
├── store-codex/ # Codex service DB
|
||||
├── data/
|
||||
│ ├── sessions/ # Per-group Claude sessions (.claude/)
|
||||
│ └── attachments/ # Downloaded Discord image attachments
|
||||
├── data-codex/sessions/ # Per-group Codex sessions (.codex/)
|
||||
├── groups/ # Per-group memory and workspace (Claude Code)
|
||||
├── groups-codex/ # Per-group memory and workspace (Codex)
|
||||
└── logs/ # Service logs
|
||||
│ ├── agent-runner/ # Claude Code runner (Agent SDK)
|
||||
│ ├── codex-runner/ # Codex runner (app-server JSON-RPC)
|
||||
│ └── skills/
|
||||
│ └── agent-browser/ # Browser automation (gstack browse wrapper)
|
||||
├── groups/{name}/ # Per-group memory (CLAUDE.md)
|
||||
├── data/sessions/ # Per-group agent sessions
|
||||
├── store/ # SQLite database
|
||||
└── prompts/ # Platform-level system prompts
|
||||
```
|
||||
|
||||
### Codex App-Server Integration
|
||||
|
||||
The Codex runner (`runners/codex-runner/`) communicates with `codex app-server` via JSON-RPC over stdio:
|
||||
|
||||
- **Session persistence**: Thread IDs stored in DB, sessions saved as JSONL on disk
|
||||
- **Streaming**: `item/agentMessage/delta` notifications for real-time text
|
||||
- **Mid-turn steering**: IPC messages injected via `turn/steer` during execution
|
||||
- **Auto-approval**: `approvalPolicy: "never"` + `sandbox: "danger-full-access"`
|
||||
- **Auto-continue**: Detects text-only turns (no tool execution) and automatically retries up to 5 times to nudge the agent into actually executing tasks
|
||||
- **Multimodal input**: Image attachments converted to `localImage` input blocks in `turn/start`
|
||||
- **Per-group config**: Model, effort, MCP servers configured per channel
|
||||
|
||||
### Image Handling
|
||||
|
||||
Bidirectional image support through Discord:
|
||||
|
||||
- **Receiving** (user → agent): Discord image attachments are downloaded to `data/attachments/`, then passed as base64 `ImageBlockParam` content blocks (Claude Code) or `localImage` input blocks (Codex)
|
||||
- **Sending** (agent → user): Markdown image links `[name.png](/path)` in agent responses are automatically parsed and sent as Discord file attachments. Non-image file links are converted to readable filenames (`BuildPanel.tsx:320`)
|
||||
|
||||
### Skill Sync
|
||||
|
||||
Skills are managed from a single source of truth (`~/.claude/skills/` on the server) and automatically synced to all agent session directories at process start:
|
||||
|
||||
- Claude Code sessions: `~/.claude/skills/` + project `runners/skills/`
|
||||
- Codex sessions: Same sources, synced to per-group `.codex/` directories
|
||||
- Skills auto-register as slash commands (`/name`) in Claude Code and `$name` in Codex
|
||||
|
||||
### GroupQueue
|
||||
|
||||
`src/group-queue.ts` manages agent execution with:
|
||||
|
||||
- **Per-group serialization**: Only one agent process per group at a time
|
||||
- **Global concurrency limit**: Configurable max concurrent agents across all groups
|
||||
- **Task priority**: Scheduled tasks drain before message processing
|
||||
- **Idle preemption**: Idle agents are terminated when higher-priority tasks arrive
|
||||
- **Exponential backoff**: Retries with backoff on processing failure
|
||||
|
||||
## Setup
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Linux (Ubuntu 22.04+) or macOS
|
||||
- Node.js 20+
|
||||
- Node.js 20+ (fnm recommended)
|
||||
- [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code)
|
||||
- [Codex CLI](https://github.com/openai/codex) (`npm install -g @openai/codex`)
|
||||
- Two Discord bot tokens (one per agent) — create at [Discord Developer Portal](https://discord.com/developers/applications)
|
||||
- Bun 1.0+ (for browser automation)
|
||||
- Discord bot token
|
||||
|
||||
### 1. Clone and Install
|
||||
### Install
|
||||
|
||||
```bash
|
||||
git clone https://github.com/phj1081/nanoclaw.git
|
||||
cd nanoclaw
|
||||
git clone https://github.com/phj1081/EJClaw.git
|
||||
cd EJClaw
|
||||
npm install
|
||||
npm run build:runners # installs + builds both agent-runner and codex-runner
|
||||
npm run build # builds main project
|
||||
npm run build:runners
|
||||
npm run build
|
||||
```
|
||||
|
||||
### 2. Authenticate CLIs
|
||||
### Environment
|
||||
|
||||
```bash
|
||||
# Claude Code — opens browser for OAuth login
|
||||
claude login
|
||||
|
||||
# Codex — set API key
|
||||
export OPENAI_API_KEY=sk-...
|
||||
|
||||
# Groq — for fast voice transcription (free at console.groq.com)
|
||||
export GROQ_API_KEY=gsk_...
|
||||
```
|
||||
|
||||
### 3. Environment Variables
|
||||
|
||||
Create `.env` in the project root:
|
||||
|
||||
```bash
|
||||
# .env — shared config (read by both services)
|
||||
DISCORD_BOT_TOKEN= # Claude Code Discord bot token
|
||||
# .env
|
||||
DISCORD_BOT_TOKEN= # Discord bot token
|
||||
ASSISTANT_NAME=claude # Bot trigger name (@claude)
|
||||
ANTHROPIC_API_KEY= # Or use OAuth (claude login)
|
||||
CLAUDE_CODE_OAUTH_TOKEN= # Claude Code OAuth token
|
||||
OPENAI_API_KEY= # For Codex
|
||||
GROQ_API_KEY= # For voice transcription (Groq Whisper, fast + free)
|
||||
GROQ_API_KEY= # Voice transcription (Groq Whisper)
|
||||
```
|
||||
|
||||
For dual-service setup, create `.env.codex` for Codex-specific overrides:
|
||||
### Systemd Services (Linux)
|
||||
|
||||
```bash
|
||||
# .env.codex — Codex service secrets (loaded via systemd EnvironmentFile)
|
||||
DISCORD_BOT_TOKEN= # Codex Discord bot token (different from above)
|
||||
```
|
||||
|
||||
> **Security**: Never put tokens in systemd service files or commit them to git. Use `.env` files with restricted permissions (`chmod 600`).
|
||||
|
||||
### 4. Systemd Services (Linux)
|
||||
|
||||
Create `~/.config/systemd/user/nanoclaw.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=NanoClaw Claude Code
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/path/to/node /path/to/nanoclaw/dist/index.js
|
||||
WorkingDirectory=/path/to/nanoclaw
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
Environment=HOME=/home/youruser
|
||||
Environment=PATH=/path/to/node/bin:/usr/local/bin:/usr/bin:/bin
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
```
|
||||
|
||||
Create `~/.config/systemd/user/nanoclaw-codex.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=NanoClaw Codex
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=/path/to/nanoclaw/.env.codex
|
||||
Type=simple
|
||||
ExecStart=/path/to/node /path/to/nanoclaw/dist/index.js
|
||||
WorkingDirectory=/path/to/nanoclaw
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
Environment=HOME=/home/youruser
|
||||
Environment=PATH=/path/to/node/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=ASSISTANT_NAME=codex
|
||||
Environment=NANOCLAW_STORE_DIR=/path/to/nanoclaw/store-codex
|
||||
Environment=NANOCLAW_DATA_DIR=/path/to/nanoclaw/data-codex
|
||||
Environment=NANOCLAW_GROUPS_DIR=/path/to/nanoclaw/groups-codex
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
```
|
||||
|
||||
Then enable and start:
|
||||
|
||||
```bash
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable nanoclaw nanoclaw-codex
|
||||
systemctl --user start nanoclaw nanoclaw-codex
|
||||
|
||||
@@ -226,46 +108,13 @@ journalctl --user -u nanoclaw -f
|
||||
journalctl --user -u nanoclaw-codex -f
|
||||
```
|
||||
|
||||
### 5. Register Discord Channels
|
||||
|
||||
Channels are stored in each service's SQLite database (`registered_groups` table). Use the IPC auth endpoint or insert directly:
|
||||
|
||||
```bash
|
||||
# Example: register a channel for Claude Code
|
||||
sqlite3 store/nanoclaw.db "INSERT INTO registered_groups (jid, name, folder, agent_type, trigger_pattern) VALUES ('dc:CHANNEL_ID', 'my-channel', 'my-channel', 'claude-code', '@claude');"
|
||||
|
||||
# Example: register a channel for Codex
|
||||
sqlite3 store-codex/nanoclaw.db "INSERT INTO registered_groups (jid, name, folder, agent_type, trigger_pattern) VALUES ('dc:CHANNEL_ID', 'my-channel', 'my-channel', 'codex', '@codex');"
|
||||
```
|
||||
|
||||
Fields:
|
||||
|
||||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| `jid` | `dc:<discord_channel_id>` |
|
||||
| `name` | Display name |
|
||||
| `folder` | Group folder name (workspace directory) |
|
||||
| `agent_type` | `claude-code`, `codex`, or `both` |
|
||||
| `trigger_pattern` | Regex for activation (e.g., `@claude`) |
|
||||
| `work_dir` | Optional working directory override |
|
||||
| `agent_config` | Optional JSON (e.g., `{"codexEffort":"high"}`) |
|
||||
|
||||
### macOS (launchd)
|
||||
|
||||
```bash
|
||||
launchctl load ~/Library/LaunchAgents/com.nanoclaw.plist
|
||||
launchctl load ~/Library/LaunchAgents/com.nanoclaw-codex.plist
|
||||
launchctl kickstart -k gui/$(id -u)/com.nanoclaw
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
npm install # Install dependencies
|
||||
npm run build # Build main project
|
||||
npm run build:runners # Install + build both runners
|
||||
npm run dev # Dev mode with hot reload
|
||||
npm test # Run tests
|
||||
npm run build # Build main project
|
||||
npm run build:runners # Install + build both runners
|
||||
npm run dev # Dev mode with hot reload
|
||||
npm test # Run tests
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
@@ -6,19 +6,20 @@ allowed-tools: Bash(agent-browser:*)
|
||||
|
||||
# Browser Automation with agent-browser
|
||||
|
||||
Powered by gstack browse — persistent headless Chromium with ~100ms per command.
|
||||
|
||||
## Quick start
|
||||
|
||||
```bash
|
||||
agent-browser open <url> # Navigate to page
|
||||
agent-browser goto <url> # Navigate to page
|
||||
agent-browser snapshot -i # Get interactive elements with refs
|
||||
agent-browser click @e1 # Click element by ref
|
||||
agent-browser fill @e2 "text" # Fill input by ref
|
||||
agent-browser close # Close browser
|
||||
```
|
||||
|
||||
## Core workflow
|
||||
|
||||
1. Navigate: `agent-browser open <url>`
|
||||
1. Navigate: `agent-browser goto <url>`
|
||||
2. Snapshot: `agent-browser snapshot -i` (returns elements with refs like `@e1`, `@e2`)
|
||||
3. Interact using refs from the snapshot
|
||||
4. Re-snapshot after navigation or significant DOM changes
|
||||
@@ -28,11 +29,11 @@ agent-browser close # Close browser
|
||||
### Navigation
|
||||
|
||||
```bash
|
||||
agent-browser open <url> # Navigate to URL
|
||||
agent-browser goto <url> # Navigate to URL
|
||||
agent-browser back # Go back
|
||||
agent-browser forward # Go forward
|
||||
agent-browser reload # Reload page
|
||||
agent-browser close # Close browser
|
||||
agent-browser url # Get current URL
|
||||
```
|
||||
|
||||
### Snapshot (page analysis)
|
||||
@@ -43,43 +44,45 @@ agent-browser snapshot -i # Interactive elements only (recommended)
|
||||
agent-browser snapshot -c # Compact output
|
||||
agent-browser snapshot -d 3 # Limit depth to 3
|
||||
agent-browser snapshot -s "#main" # Scope to CSS selector
|
||||
agent-browser snapshot -D # Diff against previous snapshot
|
||||
agent-browser snapshot -a # Annotated screenshot with ref labels
|
||||
agent-browser snapshot -C # Find non-ARIA clickable elements (@c refs)
|
||||
```
|
||||
|
||||
### Interactions (use @refs from snapshot)
|
||||
|
||||
```bash
|
||||
agent-browser click @e1 # Click
|
||||
agent-browser dblclick @e1 # Double-click
|
||||
agent-browser fill @e2 "text" # Clear and type
|
||||
agent-browser type @e2 "text" # Type without clearing
|
||||
agent-browser press Enter # Press key
|
||||
agent-browser hover @e1 # Hover
|
||||
agent-browser check @e1 # Check checkbox
|
||||
agent-browser uncheck @e1 # Uncheck checkbox
|
||||
agent-browser select @e1 "value" # Select dropdown option
|
||||
agent-browser scroll down 500 # Scroll page
|
||||
agent-browser upload @e1 file.pdf # Upload files
|
||||
agent-browser viewport 1280x720 # Set viewport size
|
||||
```
|
||||
|
||||
### Get information
|
||||
### Content extraction
|
||||
|
||||
```bash
|
||||
agent-browser get text @e1 # Get element text
|
||||
agent-browser get html @e1 # Get innerHTML
|
||||
agent-browser get value @e1 # Get input value
|
||||
agent-browser get attr @e1 href # Get attribute
|
||||
agent-browser get title # Get page title
|
||||
agent-browser get url # Get current URL
|
||||
agent-browser get count ".item" # Count matching elements
|
||||
agent-browser text # Get all page text
|
||||
agent-browser text @e1 # Get element text
|
||||
agent-browser html @e1 # Get innerHTML
|
||||
agent-browser links # Get all links
|
||||
agent-browser forms # Get all forms
|
||||
agent-browser accessibility # Full accessibility tree
|
||||
```
|
||||
|
||||
### Screenshots & PDF
|
||||
|
||||
```bash
|
||||
agent-browser screenshot # Save to temp directory
|
||||
agent-browser screenshot path.png # Save to specific path
|
||||
agent-browser screenshot --full # Full page
|
||||
agent-browser pdf output.pdf # Save as PDF
|
||||
agent-browser screenshot # Full page screenshot
|
||||
agent-browser screenshot --viewport # Viewport only
|
||||
agent-browser screenshot @e1 # Element screenshot
|
||||
agent-browser screenshot --clip x,y,w,h # Region screenshot
|
||||
agent-browser pdf output.pdf # Save as PDF
|
||||
agent-browser responsive # Multi-viewport screenshots
|
||||
```
|
||||
|
||||
### Wait
|
||||
@@ -92,54 +95,57 @@ agent-browser wait --url "**/dashboard" # Wait for URL pattern
|
||||
agent-browser wait --load networkidle # Wait for network idle
|
||||
```
|
||||
|
||||
### Semantic locators (alternative to refs)
|
||||
### Inspection & Debugging
|
||||
|
||||
```bash
|
||||
agent-browser find role button click --name "Submit"
|
||||
agent-browser find text "Sign In" click
|
||||
agent-browser find label "Email" fill "user@test.com"
|
||||
agent-browser find placeholder "Search" type "query"
|
||||
```
|
||||
|
||||
### Authentication with saved state
|
||||
|
||||
```bash
|
||||
# Login once
|
||||
agent-browser open https://app.example.com/login
|
||||
agent-browser snapshot -i
|
||||
agent-browser fill @e1 "username"
|
||||
agent-browser fill @e2 "password"
|
||||
agent-browser click @e3
|
||||
agent-browser wait --url "**/dashboard"
|
||||
agent-browser state save auth.json
|
||||
|
||||
# Later: load saved state
|
||||
agent-browser state load auth.json
|
||||
agent-browser open https://app.example.com/dashboard
|
||||
agent-browser js "document.title" # Run JavaScript expression
|
||||
agent-browser eval script.js # Run JavaScript file
|
||||
agent-browser css @e1 color # Get CSS property
|
||||
agent-browser attrs @e1 # Get all attributes
|
||||
agent-browser is visible @e1 # Check element state
|
||||
agent-browser console # View console logs
|
||||
agent-browser console --errors # Console errors only
|
||||
agent-browser network # View network requests
|
||||
agent-browser perf # Performance metrics
|
||||
```
|
||||
|
||||
### Cookies & Storage
|
||||
|
||||
```bash
|
||||
agent-browser cookies # Get all cookies
|
||||
agent-browser cookies set name value # Set cookie
|
||||
agent-browser cookies clear # Clear cookies
|
||||
agent-browser storage local # Get localStorage
|
||||
agent-browser storage local set k v # Set value
|
||||
agent-browser cookies # Get all cookies
|
||||
agent-browser storage # Get localStorage
|
||||
agent-browser storage set key value # Set localStorage value
|
||||
```
|
||||
|
||||
### JavaScript
|
||||
### Tabs
|
||||
|
||||
```bash
|
||||
agent-browser eval "document.title" # Run JavaScript
|
||||
agent-browser tabs # List open tabs
|
||||
agent-browser tab <id> # Switch to tab
|
||||
agent-browser newtab <url> # Open new tab
|
||||
agent-browser closetab # Close current tab
|
||||
```
|
||||
|
||||
### Dialog handling
|
||||
|
||||
```bash
|
||||
agent-browser dialog-accept # Accept dialog (default behavior)
|
||||
agent-browser dialog-accept "text" # Accept prompt with text
|
||||
agent-browser dialog-dismiss # Dismiss dialog
|
||||
```
|
||||
|
||||
### Compare
|
||||
|
||||
```bash
|
||||
agent-browser diff <url1> <url2> # Compare two pages
|
||||
```
|
||||
|
||||
## Example: Form submission
|
||||
|
||||
```bash
|
||||
agent-browser open https://example.com/form
|
||||
agent-browser goto https://example.com/form
|
||||
agent-browser snapshot -i
|
||||
# Output shows: textbox "Email" [ref=e1], textbox "Password" [ref=e2], button "Submit" [ref=e3]
|
||||
# Output: @e1 [textbox] "Email", @e2 [textbox] "Password", @e3 [button] "Submit"
|
||||
|
||||
agent-browser fill @e1 "user@example.com"
|
||||
agent-browser fill @e2 "password123"
|
||||
@@ -151,9 +157,15 @@ agent-browser snapshot -i # Check result
|
||||
## Example: Data extraction
|
||||
|
||||
```bash
|
||||
agent-browser open https://example.com/products
|
||||
agent-browser goto https://example.com/products
|
||||
agent-browser snapshot -i
|
||||
agent-browser get text @e1 # Get product title
|
||||
agent-browser get attr @e2 href # Get link URL
|
||||
agent-browser screenshot products.png
|
||||
agent-browser text @e1 # Get product title
|
||||
agent-browser screenshot items.png
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Server auto-starts on first command, auto-shuts after 30min idle
|
||||
- ~100ms per command after initial startup (~3s first time)
|
||||
- Refs (`@e1`, `@e2`) are assigned from accessibility tree — re-snapshot after DOM changes
|
||||
- `@c` refs from `-C` flag target non-ARIA clickable elements (divs with onclick, cursor:pointer)
|
||||
|
||||
Reference in New Issue
Block a user