feat: add abs alias, refresh extension panel, and bump to 0.16.1-fork.1
This commit is contained in:
@@ -5,7 +5,7 @@ Stealth-first fork of `agent-browser` for production browser automation under an
|
||||
This README focuses on stealth architecture and principles. For full command coverage inherited from upstream, use:
|
||||
|
||||
- upstream docs: <https://github.com/vercel-labs/agent-browser>
|
||||
- local help: `agent-browser --help`
|
||||
- local help: `agent-browser --help` (short alias: `abs --help`)
|
||||
|
||||
## What This Fork Optimizes
|
||||
|
||||
@@ -20,7 +20,7 @@ This README focuses on stealth architecture and principles. For full command cov
|
||||
People often ask this: "What's the anti-detection approach compared to `agent-browser-stealth` on npm?"
|
||||
|
||||
- `agent-browser-stealth` on npm is the package name for this fork.
|
||||
- The CLI keeps upstream-compatible command names (`agent-browser` is still the main executable, with `agent-browser-stealth` as an alias).
|
||||
- The CLI keeps upstream-compatible command names (`agent-browser` is still the main executable, with `agent-browser-stealth` and `abs` as aliases).
|
||||
- The practical difference vs upstream `agent-browser` is not one single "stealth switch"; it is a defense-in-depth stack designed for anti-bot pressure.
|
||||
|
||||
The core idea is layered hardening across the full automation lifecycle:
|
||||
@@ -40,6 +40,8 @@ Goal: reduce detection probability and improve stability in production automatio
|
||||
```bash
|
||||
npm install -g agent-browser-stealth
|
||||
agent-browser install
|
||||
# same CLI, short alias
|
||||
abs install
|
||||
```
|
||||
|
||||
### Minimal Usage
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "agent-browser-stealth"
|
||||
version = "0.16.1-fork.0"
|
||||
version = "0.16.1-fork.1"
|
||||
edition = "2021"
|
||||
description = "Stealth browser automation CLI for AI agents with anti-bot evasions"
|
||||
license = "Apache-2.0"
|
||||
|
||||
@@ -2393,6 +2393,7 @@ pub fn print_help() {
|
||||
agent-browser - fast browser automation CLI for AI agents
|
||||
|
||||
Usage: agent-browser <command> [args] [options]
|
||||
Aliases: agent-browser, agent-browser-stealth, abs
|
||||
|
||||
Core Commands:
|
||||
open <url> Navigate to URL
|
||||
|
||||
@@ -4,6 +4,8 @@ export const metadata = pageMetadata('commands');
|
||||
|
||||
# Commands
|
||||
|
||||
Executable aliases: `agent-browser`, `agent-browser-stealth`, `abs`.
|
||||
|
||||
## Core
|
||||
|
||||
```bash
|
||||
|
||||
@@ -14,6 +14,8 @@ brew install agent-browser # macOS
|
||||
npx agent-browser-stealth open example.com
|
||||
```
|
||||
|
||||
Executable aliases after install: `agent-browser`, `agent-browser-stealth`, and `abs`.
|
||||
|
||||
## Features
|
||||
|
||||
- **Agent-first** - Compact text output uses fewer tokens than JSON, designed for AI context efficiency
|
||||
|
||||
@@ -1,119 +1,192 @@
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
--bg: #111827;
|
||||
--card: #1f2937;
|
||||
--border: #374151;
|
||||
--text: #f9fafb;
|
||||
--muted: #d1d5db;
|
||||
--accent: #22c55e;
|
||||
--bg: #0d1117;
|
||||
--panel: #161b22;
|
||||
--item-bg: rgba(255, 255, 255, 0.03);
|
||||
--item-hover: rgba(255, 255, 255, 0.06);
|
||||
--border: #30363d;
|
||||
--border-focus: #484f58;
|
||||
--text-main: #e6edf3;
|
||||
--text-muted: #848d97;
|
||||
--accent: #2f81f7;
|
||||
--accent-soft: rgba(47, 129, 247, 0.1);
|
||||
--success: #3fb950;
|
||||
--warning: #d29922;
|
||||
--font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 12px;
|
||||
background: radial-gradient(circle at top left, #1f2937, #111827);
|
||||
color: var(--text);
|
||||
font:
|
||||
13px/1.5 -apple-system,
|
||||
BlinkMacSystemFont,
|
||||
'Segoe UI',
|
||||
sans-serif;
|
||||
padding: 20px;
|
||||
background-color: var(--bg);
|
||||
color: var(--text-main);
|
||||
font-family: var(--font-family);
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* Scrollbar */
|
||||
::-webkit-scrollbar { width: 8px; }
|
||||
::-webkit-scrollbar-track { background: transparent; }
|
||||
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 10px; }
|
||||
::-webkit-scrollbar-thumb:hover { background: var(--border-focus); }
|
||||
|
||||
header {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 15px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
button {
|
||||
background: #0f172a;
|
||||
color: var(--text);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 6px 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
border-color: var(--accent);
|
||||
h1::before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background: var(--accent);
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 0 10px var(--accent);
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
button {
|
||||
all: unset;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 6px 12px;
|
||||
background: var(--panel);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
color: var(--text-main);
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: var(--item-hover);
|
||||
border-color: var(--border-focus);
|
||||
}
|
||||
|
||||
#refresh-btn {
|
||||
background: var(--accent);
|
||||
border-color: var(--accent);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
#refresh-btn:hover {
|
||||
background: #4493f8;
|
||||
border-color: #4493f8;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: color-mix(in srgb, var(--card) 88%, #000 12%);
|
||||
background: var(--panel);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
padding: 16px;
|
||||
margin-bottom: 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
color: var(--text-muted);
|
||||
margin: 0 0 12px 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.stack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.session-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 6px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.session-title strong {
|
||||
.session-title h4 {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
margin: 6px 0;
|
||||
gap: 4px;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.tag {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 999px;
|
||||
padding: 2px 7px;
|
||||
color: var(--muted);
|
||||
font-size: 12px;
|
||||
background: var(--accent-soft);
|
||||
color: var(--accent);
|
||||
border: 1px solid transparent;
|
||||
padding: 1px 6px;
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
gap: 1px; /* Divider effect */
|
||||
background: var(--border);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.item {
|
||||
border: 1px solid color-mix(in srgb, var(--border) 85%, #000 15%);
|
||||
border-radius: 8px;
|
||||
padding: 6px 7px;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
overflow: hidden;
|
||||
background: var(--panel);
|
||||
padding: 10px 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
transition: background 0.1s ease;
|
||||
}
|
||||
|
||||
.item:hover {
|
||||
background: var(--item-hover);
|
||||
}
|
||||
|
||||
.item-title {
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
color: var(--text-main);
|
||||
}
|
||||
|
||||
.item-url {
|
||||
color: var(--muted);
|
||||
color: var(--text-muted);
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
@@ -122,9 +195,45 @@ button:hover {
|
||||
|
||||
.row-actions {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
gap: 4px;
|
||||
margin-top: 12px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.row-actions button {
|
||||
padding: 4px 8px;
|
||||
font-size: 11px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.empty {
|
||||
color: var(--muted);
|
||||
color: var(--text-muted);
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
||||
background: rgba(110, 118, 129, 0.4);
|
||||
padding: 2px 5px;
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
#summary code {
|
||||
color: var(--warning);
|
||||
}
|
||||
|
||||
/* Summary Grid */
|
||||
#summary .tags {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
#summary .tag {
|
||||
text-align: center;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
@@ -16,45 +16,54 @@ function createTag(text) {
|
||||
}
|
||||
|
||||
function renderSummary(state) {
|
||||
summaryEl.innerHTML = '';
|
||||
summaryEl.innerHTML = '<h3>Overview</h3>';
|
||||
const options = state.options || {};
|
||||
const title = document.createElement('div');
|
||||
title.innerHTML = `<strong>Overview</strong> · extensionId: <code>${state.extensionId}</code>`;
|
||||
|
||||
const idInfo = document.createElement('div');
|
||||
idInfo.style.marginBottom = '12px';
|
||||
idInfo.style.fontSize = '11px';
|
||||
idInfo.style.color = 'var(--text-muted)';
|
||||
idInfo.innerHTML = `Extension ID: <code>${state.extensionId}</code>`;
|
||||
summaryEl.appendChild(idInfo);
|
||||
|
||||
const tags = document.createElement('div');
|
||||
tags.className = 'tags';
|
||||
tags.appendChild(createTag(`sessions: ${state.totals.sessions}`));
|
||||
tags.appendChild(createTag(`tabs: ${state.totals.tabs}`));
|
||||
tags.appendChild(createTag(`Sessions: ${state.totals.sessions}`));
|
||||
tags.appendChild(createTag(`Tabs: ${state.totals.tabs}`));
|
||||
tags.appendChild(
|
||||
createTag(`isolation: ${options.strictWindowIsolation === false ? 'off' : 'on'}`)
|
||||
createTag(`Isolation: ${options.strictWindowIsolation === false ? 'Off' : 'On'}`)
|
||||
);
|
||||
tags.appendChild(
|
||||
createTag(`activation-guard: ${options.suppressCrossWindowActivation === false ? 'off' : 'on'}`)
|
||||
createTag(`Guard: ${options.suppressCrossWindowActivation === false ? 'Off' : 'On'}`)
|
||||
);
|
||||
tags.appendChild(
|
||||
createTag(`auto-clean: ${options.autoCleanEmptyGroups === false ? 'off' : 'on'}`)
|
||||
createTag(`Auto-Clean: ${options.autoCleanEmptyGroups === false ? 'Off' : 'On'}`)
|
||||
);
|
||||
|
||||
const optionActions = document.createElement('div');
|
||||
optionActions.className = 'row-actions';
|
||||
|
||||
const isolationBtn = document.createElement('button');
|
||||
isolationBtn.type = 'button';
|
||||
isolationBtn.textContent =
|
||||
options.strictWindowIsolation === false ? 'Enable Isolation' : 'Disable Isolation';
|
||||
isolationBtn.addEventListener('click', async () => {
|
||||
const createOptionBtn = (text, active, onClick) => {
|
||||
const btn = document.createElement('button');
|
||||
btn.type = 'button';
|
||||
btn.textContent = text;
|
||||
if (active) btn.style.borderColor = 'var(--accent)';
|
||||
btn.addEventListener('click', onClick);
|
||||
return btn;
|
||||
};
|
||||
|
||||
optionActions.appendChild(
|
||||
createOptionBtn('Strict Isolation', options.strictWindowIsolation !== false, async () => {
|
||||
await send({
|
||||
type: 'AB_PANEL_SET_OPTIONS',
|
||||
options: { ...options, strictWindowIsolation: options.strictWindowIsolation === false },
|
||||
});
|
||||
await refresh();
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
const guardBtn = document.createElement('button');
|
||||
guardBtn.type = 'button';
|
||||
guardBtn.textContent =
|
||||
options.suppressCrossWindowActivation === false ? 'Enable Guard' : 'Disable Guard';
|
||||
guardBtn.addEventListener('click', async () => {
|
||||
optionActions.appendChild(
|
||||
createOptionBtn('Activation Guard', options.suppressCrossWindowActivation !== false, async () => {
|
||||
await send({
|
||||
type: 'AB_PANEL_SET_OPTIONS',
|
||||
options: {
|
||||
@@ -63,13 +72,11 @@ function renderSummary(state) {
|
||||
},
|
||||
});
|
||||
await refresh();
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
const autoCleanBtn = document.createElement('button');
|
||||
autoCleanBtn.type = 'button';
|
||||
autoCleanBtn.textContent =
|
||||
options.autoCleanEmptyGroups === false ? 'Enable Auto-Clean' : 'Disable Auto-Clean';
|
||||
autoCleanBtn.addEventListener('click', async () => {
|
||||
optionActions.appendChild(
|
||||
createOptionBtn('Auto-Clean', options.autoCleanEmptyGroups !== false, async () => {
|
||||
await send({
|
||||
type: 'AB_PANEL_SET_OPTIONS',
|
||||
options: {
|
||||
@@ -78,24 +85,20 @@ function renderSummary(state) {
|
||||
},
|
||||
});
|
||||
await refresh();
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
optionActions.appendChild(isolationBtn);
|
||||
optionActions.appendChild(guardBtn);
|
||||
optionActions.appendChild(autoCleanBtn);
|
||||
|
||||
summaryEl.appendChild(title);
|
||||
summaryEl.appendChild(tags);
|
||||
summaryEl.appendChild(optionActions);
|
||||
}
|
||||
|
||||
function renderSessions(state) {
|
||||
sessionsEl.innerHTML = '';
|
||||
sessionsEl.innerHTML = '<h3>Active Sessions</h3>';
|
||||
|
||||
if (!state.sessions || state.sessions.length === 0) {
|
||||
const empty = document.createElement('div');
|
||||
empty.className = 'card empty';
|
||||
empty.textContent = 'No managed sessions yet.';
|
||||
empty.textContent = 'No active sessions monitored.';
|
||||
sessionsEl.appendChild(empty);
|
||||
return;
|
||||
}
|
||||
@@ -107,31 +110,71 @@ function renderSessions(state) {
|
||||
const titleRow = document.createElement('div');
|
||||
titleRow.className = 'session-title';
|
||||
|
||||
const titleLeft = document.createElement('strong');
|
||||
const titleLeft = document.createElement('h4');
|
||||
titleLeft.textContent = session.session;
|
||||
|
||||
const actions = document.createElement('div');
|
||||
actions.className = 'row-actions';
|
||||
|
||||
const focusBtn = document.createElement('button');
|
||||
focusBtn.type = 'button';
|
||||
focusBtn.textContent = 'Focus';
|
||||
focusBtn.addEventListener('click', async () => {
|
||||
await send({ type: 'AB_PANEL_FOCUS_SESSION', session: session.session });
|
||||
await refresh();
|
||||
});
|
||||
|
||||
titleRow.appendChild(titleLeft);
|
||||
titleRow.appendChild(focusBtn);
|
||||
|
||||
const tags = document.createElement('div');
|
||||
tags.className = 'tags';
|
||||
tags.appendChild(createTag(`Window: ${session.windowId ?? 'N/A'}`));
|
||||
tags.appendChild(createTag(`Tabs: ${session.tabs.length}`));
|
||||
|
||||
if (session.group) {
|
||||
tags.appendChild(createTag(`G: ${session.group.title || 'Untitled'}`));
|
||||
}
|
||||
|
||||
if (session.allowedDomains && session.allowedDomains.length > 0) {
|
||||
tags.appendChild(createTag(`Allowlist: ${session.allowedDomains.length} domains`));
|
||||
}
|
||||
|
||||
const list = document.createElement('div');
|
||||
list.className = 'list';
|
||||
for (const tab of session.tabs.slice(0, 10)) {
|
||||
const item = document.createElement('div');
|
||||
item.className = 'item';
|
||||
|
||||
const t = document.createElement('div');
|
||||
t.className = 'item-title';
|
||||
if (tab.active) {
|
||||
const dot = document.createElement('span');
|
||||
dot.textContent = '●';
|
||||
dot.style.color = 'var(--success)';
|
||||
dot.style.marginRight = '6px';
|
||||
dot.style.fontSize = '10px';
|
||||
t.appendChild(dot);
|
||||
}
|
||||
t.appendChild(document.createTextNode(tab.title || '(Untitled)'));
|
||||
|
||||
const u = document.createElement('div');
|
||||
u.className = 'item-url';
|
||||
u.textContent = tab.url || 'about:blank';
|
||||
|
||||
item.appendChild(t);
|
||||
item.appendChild(u);
|
||||
list.appendChild(item);
|
||||
}
|
||||
|
||||
const footerActions = document.createElement('div');
|
||||
footerActions.className = 'row-actions';
|
||||
|
||||
const keepBtn = document.createElement('button');
|
||||
keepBtn.type = 'button';
|
||||
keepBtn.textContent = 'Keep Only This';
|
||||
keepBtn.textContent = 'Isolate Session';
|
||||
keepBtn.addEventListener('click', async () => {
|
||||
await send({ type: 'AB_PANEL_CLOSE_OTHER_SESSION_TABS', session: session.session });
|
||||
await refresh();
|
||||
});
|
||||
|
||||
const policyBtn = document.createElement('button');
|
||||
policyBtn.type = 'button';
|
||||
policyBtn.textContent = 'Set Allowlist';
|
||||
policyBtn.textContent = 'Config Policy';
|
||||
policyBtn.addEventListener('click', async () => {
|
||||
const current = (session.allowedDomains || []).join(',');
|
||||
const input = window.prompt('Allowed domains (comma-separated)', current);
|
||||
@@ -144,62 +187,19 @@ function renderSessions(state) {
|
||||
await refresh();
|
||||
});
|
||||
|
||||
actions.appendChild(focusBtn);
|
||||
actions.appendChild(keepBtn);
|
||||
actions.appendChild(policyBtn);
|
||||
|
||||
titleRow.appendChild(titleLeft);
|
||||
titleRow.appendChild(actions);
|
||||
|
||||
const tags = document.createElement('div');
|
||||
tags.className = 'tags';
|
||||
tags.appendChild(createTag(`window: ${session.windowId ?? 'n/a'}`));
|
||||
tags.appendChild(createTag(`tabs: ${session.tabs.length}`));
|
||||
|
||||
if (session.group) {
|
||||
tags.appendChild(createTag(`group: ${session.group.title || session.group.id}`));
|
||||
tags.appendChild(createTag(`color: ${session.group.color}`));
|
||||
tags.appendChild(createTag(`collapsed: ${session.group.collapsed}`));
|
||||
}
|
||||
|
||||
if (session.allowedDomains && session.allowedDomains.length > 0) {
|
||||
tags.appendChild(createTag(`allowlist: ${session.allowedDomains.join(', ')}`));
|
||||
}
|
||||
|
||||
if (session.riskHints && session.riskHints.length > 0) {
|
||||
for (const hint of session.riskHints) {
|
||||
tags.appendChild(createTag(`risk: ${hint}`));
|
||||
}
|
||||
}
|
||||
|
||||
const list = document.createElement('div');
|
||||
list.className = 'list';
|
||||
for (const tab of session.tabs.slice(0, 10)) {
|
||||
const item = document.createElement('div');
|
||||
item.className = 'item';
|
||||
|
||||
const t = document.createElement('div');
|
||||
t.className = 'item-title';
|
||||
t.textContent = `${tab.active ? '● ' : ''}${tab.title || '(untitled)'}`;
|
||||
|
||||
const u = document.createElement('div');
|
||||
u.className = 'item-url';
|
||||
u.textContent = tab.url || 'about:blank';
|
||||
|
||||
item.appendChild(t);
|
||||
item.appendChild(u);
|
||||
list.appendChild(item);
|
||||
}
|
||||
footerActions.appendChild(keepBtn);
|
||||
footerActions.appendChild(policyBtn);
|
||||
|
||||
card.appendChild(titleRow);
|
||||
card.appendChild(tags);
|
||||
card.appendChild(list);
|
||||
card.appendChild(footerActions);
|
||||
sessionsEl.appendChild(card);
|
||||
}
|
||||
}
|
||||
|
||||
function renderDownloads(state) {
|
||||
downloadsEl.innerHTML = '<strong>Recent Downloads</strong>';
|
||||
downloadsEl.innerHTML = '<h3>Recent Downloads</h3>';
|
||||
|
||||
const list = document.createElement('div');
|
||||
list.className = 'list';
|
||||
|
||||
+3
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "agent-browser-stealth",
|
||||
"version": "0.16.1-fork.0",
|
||||
"version": "0.16.1-fork.1",
|
||||
"description": "Stealth browser automation CLI for AI agents with anti-bot evasions",
|
||||
"type": "module",
|
||||
"main": "dist/daemon.js",
|
||||
@@ -12,7 +12,8 @@
|
||||
],
|
||||
"bin": {
|
||||
"agent-browser-stealth": "./bin/agent-browser.js",
|
||||
"agent-browser": "./bin/agent-browser.js"
|
||||
"agent-browser": "./bin/agent-browser.js",
|
||||
"abs": "./bin/agent-browser.js"
|
||||
},
|
||||
"scripts": {
|
||||
"prepare": "husky",
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
name: agent-browser
|
||||
description: Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction.
|
||||
allowed-tools: Bash(npx agent-browser-stealth:*), Bash(npx agent-browser:*), Bash(agent-browser:*)
|
||||
allowed-tools: Bash(npx agent-browser-stealth:*), Bash(npx agent-browser:*), Bash(agent-browser:*), Bash(abs:*)
|
||||
---
|
||||
|
||||
# Browser Automation with agent-browser
|
||||
|
||||
Install package: `pnpm add -g agent-browser-stealth` (CLI command remains `agent-browser` for compatibility). If global install is unavailable in your environment, use `pnpm dlx agent-browser-stealth <command>` for one-off runs.
|
||||
Install package: `pnpm add -g agent-browser-stealth` (CLI commands: `agent-browser`, `agent-browser-stealth`, and short alias `abs`). If global install is unavailable in your environment, use `pnpm dlx agent-browser-stealth <command>` for one-off runs.
|
||||
|
||||
## Core Workflow
|
||||
|
||||
|
||||
Reference in New Issue
Block a user