@polderlabs/bizar 5.6.0-beta.6 → 5.6.0-beta.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bizar-dash/skills/agent-browser/SKILL.md +181 -0
- package/bizar-dash/src/server/mods-loader.mjs +1 -1
- package/bizar-dash/tests/{no-agent-browser.node.test.mjs → no-browser-harness.node.test.mjs} +26 -26
- package/cli/agent-browser-up.sh +136 -0
- package/cli/agent-browser-update.mjs +322 -0
- package/cli/agent-browser-update.test.mjs +86 -0
- package/cli/bin.mjs +5 -3
- package/cli/commands/util.mjs +68 -4
- package/cli/doctor.mjs +2 -2
- package/cli/doctor.test.mjs +1 -1
- package/cli/provision.mjs +38 -0
- package/config/AGENTS.md +6 -6
- package/config/agents/_shared/AGENT_BASELINE.md +5 -5
- package/config/agents/agent-browser.md +90 -0
- package/config/agents/odin.md +1 -1
- package/install.sh +40 -3
- package/package.json +1 -1
- package/packages/sdk/package.json +1 -1
- package/plugins/bizar/index.ts +23 -1
- package/plugins/bizar/src/tools/agent-browser.ts +315 -0
- package/plugins/bizar/src/tools/bg-spawn.ts +1 -1
- package/plugins/bizar/tests/tools/agent-browser.test.ts +98 -0
- package/plugins/bizar/tests/tools/bg-spawn-delegation.test.ts +2 -2
- package/plugins/bizar/tests/tools/bg-spawn-http.test.ts +1 -1
- package/cli/browser-harness-up.sh +0 -193
- package/config/agents/browser-harness.md +0 -72
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-browser
|
|
3
|
+
description: Self-healing browser automation CLI for AI agents — drives Chrome for Testing via 100+ typed CLI commands, native MCP stdio server, snapshot-based element refs (`@e2`), and a plugin system.
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
status: active
|
|
6
|
+
created_by: sprint MS-2026-05
|
|
7
|
+
use_count: 0
|
|
8
|
+
failure_count: 0
|
|
9
|
+
last_used: null
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# agent-browser
|
|
13
|
+
|
|
14
|
+
`agent-browser` is a **native Rust CLI** from [vercel-labs](https://github.com/vercel-labs/agent-browser)
|
|
15
|
+
(~38K★) that exposes a complete browser-automation surface to AI agents.
|
|
16
|
+
|
|
17
|
+
## Why this skill
|
|
18
|
+
|
|
19
|
+
- Bizar dispatches a browser-primary agent (`agent-browser`) for any task
|
|
20
|
+
that requires real-browser verification of a web app: clicking buttons,
|
|
21
|
+
filling forms, taking screenshots, reading accessibility trees.
|
|
22
|
+
- agent-browser replaces the v5.x `browser-harness` (Python + uv) which
|
|
23
|
+
was slow, fragile, and lacked MCP integration. See `docs/migration-guide.md`
|
|
24
|
+
for the migration rationale.
|
|
25
|
+
|
|
26
|
+
## When to use
|
|
27
|
+
|
|
28
|
+
Use this skill when the task requires:
|
|
29
|
+
|
|
30
|
+
- "Take a screenshot of `<url>`"
|
|
31
|
+
- "Click button X, verify the result"
|
|
32
|
+
- "Fill in the login form, click submit"
|
|
33
|
+
- "Find a bug that's only visible in the rendered page"
|
|
34
|
+
- "Verify the dashboard's tab navigation works end-to-end"
|
|
35
|
+
|
|
36
|
+
Do not use this skill for:
|
|
37
|
+
|
|
38
|
+
- Editing code (the browser-primary agent has edit/write **denied**)
|
|
39
|
+
- Long-running background automation (use Cline agent teams instead)
|
|
40
|
+
- Non-Chromium browsers (Chrome for Testing only)
|
|
41
|
+
|
|
42
|
+
## Quick start
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Install (one-time)
|
|
46
|
+
npm install -g agent-browser
|
|
47
|
+
agent-browser install # downloads Chrome for Testing
|
|
48
|
+
|
|
49
|
+
# Ensure the daemon is up
|
|
50
|
+
bizar browser-agent-up start # wrapper around cli/agent-browser-up.sh
|
|
51
|
+
|
|
52
|
+
# Drive the browser
|
|
53
|
+
agent-browser open example.com
|
|
54
|
+
agent-browser snapshot --json
|
|
55
|
+
agent-browser click @e2
|
|
56
|
+
agent-browser fill @e3 "hello"
|
|
57
|
+
agent-browser screenshot page.png
|
|
58
|
+
agent-browser close
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Command reference
|
|
62
|
+
|
|
63
|
+
The full command set has 100+ commands. The most common:
|
|
64
|
+
|
|
65
|
+
| Command | Purpose |
|
|
66
|
+
| --- | --- |
|
|
67
|
+
| `agent-browser open <url>` | Launch + navigate (aliases: `goto`, `navigate`) |
|
|
68
|
+
| `agent-browser read [url]` | Fetch agent-readable text from URL or active tab |
|
|
69
|
+
| `agent-browser snapshot [--json]` | Accessibility tree with refs (`@e1`, `@e2`, ...) |
|
|
70
|
+
| `agent-browser click <sel>` | Click — accepts ref (`@e2`) or selector (`#submit`) |
|
|
71
|
+
| `agent-browser fill <sel> <text>` | Clear + fill |
|
|
72
|
+
| `agent-browser type <sel> <text>` | Type without clear |
|
|
73
|
+
| `agent-browser press <key>` | Press key (Enter, Tab, Control+a) |
|
|
74
|
+
| `agent-browser get <what> <sel>` | Get text / html / attr |
|
|
75
|
+
| `agent-browser screenshot <path>` | Screenshot to file (PNG) |
|
|
76
|
+
| `agent-browser find role/label/text` | Semantic find (returns ref) |
|
|
77
|
+
| `agent-browser wait <what>` | Wait for selector / load / network idle |
|
|
78
|
+
| `agent-browser eval <js>` | Evaluate JavaScript |
|
|
79
|
+
| `agent-browser tab list/open/close/switch` | Tab management |
|
|
80
|
+
| `agent-browser close` | Close the browser |
|
|
81
|
+
| `agent-browser doctor` | Self-diagnostics |
|
|
82
|
+
| `agent-browser mcp` | Start MCP stdio server |
|
|
83
|
+
| `agent-browser chat "..."` | Natural-language browser tasks |
|
|
84
|
+
| `agent-browser skills list/get` | Bundled skills (this skill is in the catalog) |
|
|
85
|
+
|
|
86
|
+
## MCP integration
|
|
87
|
+
|
|
88
|
+
Cline registers `agent-browser` as an MCP tool server at session start via
|
|
89
|
+
`.cline/mcp.json`:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"mcpServers": {
|
|
94
|
+
"agent-browser": {
|
|
95
|
+
"command": "agent-browser",
|
|
96
|
+
"args": ["mcp", "--tools", "core"]
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Tool profiles:
|
|
103
|
+
|
|
104
|
+
- `core` — Default. Navigation, snapshots, interaction, waits, reads, screenshots,
|
|
105
|
+
JavaScript eval, close, tab basics, profile discovery. Small MCP context.
|
|
106
|
+
- `network` — Routes, request inspection, HAR, headers, credentials, offline.
|
|
107
|
+
- `state` — Cookies, storage, auth, sessions, profiles, skills.
|
|
108
|
+
- `debug` — Console/errors, tracing, profiling, recording, clipboard, plugins,
|
|
109
|
+
doctor, dashboard, install, upgrade, chat, batch.
|
|
110
|
+
- `tabs` — Back/forward/reload, tabs, windows, frames, dialogs.
|
|
111
|
+
- `react` — React tree/inspect, vitals, pushstate.
|
|
112
|
+
- `mobile` — Viewport/device/geolocation, touch, swipe, mouse, keyboard.
|
|
113
|
+
- `all` — Every MCP tool.
|
|
114
|
+
|
|
115
|
+
## Plugin system
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"plugins": [
|
|
120
|
+
{
|
|
121
|
+
"name": "vault",
|
|
122
|
+
"command": "agent-browser-plugin-vault",
|
|
123
|
+
"capabilities": ["credential.read"]
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Patterns
|
|
130
|
+
|
|
131
|
+
### Stable selectors
|
|
132
|
+
|
|
133
|
+
Prefer **refs** (`@e2`) over CSS selectors — refs survive snapshot churn.
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
agent-browser snapshot --json > snap.json
|
|
137
|
+
agent-browser click @e2
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Headless vs headed
|
|
141
|
+
|
|
142
|
+
Default is headless. Use `--headed` for visual debugging.
|
|
143
|
+
|
|
144
|
+
### Persistent profile
|
|
145
|
+
|
|
146
|
+
Set `--profile <dir>` to keep cookies / storage across runs. Default
|
|
147
|
+
is `~/.agent-browser/profile`.
|
|
148
|
+
|
|
149
|
+
### Natural-language chat
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
AI_GATEWAY_API_KEY=... agent-browser chat "summarize the page at /pricing"
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
This streams a structured response from the configured LLM provider.
|
|
156
|
+
|
|
157
|
+
## Configuration
|
|
158
|
+
|
|
159
|
+
Layered config (lowest → highest priority):
|
|
160
|
+
|
|
161
|
+
1. `~/.agent-browser/config.json` — user-level
|
|
162
|
+
2. `./agent-browser.json` — project-level
|
|
163
|
+
3. `AGENT_BROWSER_*` env vars
|
|
164
|
+
4. CLI flags
|
|
165
|
+
|
|
166
|
+
## Lessons / known limitations
|
|
167
|
+
|
|
168
|
+
- Chrome for Testing only (no Firefox / Safari / WebKit).
|
|
169
|
+
- `agent-browser install` requires network access to download Chrome
|
|
170
|
+
the first time (~150MB).
|
|
171
|
+
- The chat endpoint requires `AI_GATEWAY_API_KEY` from Vercel.
|
|
172
|
+
- The daemon binds to `127.0.0.1` by default; use `--host` to expose
|
|
173
|
+
publicly (only on trusted networks).
|
|
174
|
+
|
|
175
|
+
## See also
|
|
176
|
+
|
|
177
|
+
- [config/agents/agent-browser.md](../../config/agents/agent-browser.md) — the Cline primary agent
|
|
178
|
+
- [cli/agent-browser-up.sh](../../cli/agent-browser-up.sh) — idempotent starter
|
|
179
|
+
- https://github.com/vercel-labs/agent-browser — upstream README
|
|
180
|
+
- [docs/migration-guide.md](../../docs/migration-guide.md) — browser-harness → agent-browser rationale
|
|
181
|
+
- [research/agent-harness-survey/round-9-memory/bizar-memory-redesign.md](../../research/agent-harness-survey/round-9-memory/bizar-memory-redesign.md)
|
|
@@ -978,7 +978,7 @@ async function fetchInstructionDir(baseUrl, destDir) {
|
|
|
978
978
|
const candidates = [
|
|
979
979
|
'thor.md', 'tyr.md', 'odin.md', 'heimdall.md', 'mimir.md',
|
|
980
980
|
'frigg.md', 'vor.md', 'hermod.md', 'baldr.md', 'forseti.md',
|
|
981
|
-
'vidarr.md', 'quick.md', 'browser
|
|
981
|
+
'vidarr.md', 'quick.md', 'agent-browser.md', 'semble-search.md',
|
|
982
982
|
'plan.md', 'review.md', 'audit.md', 'init.md', 'learn.md',
|
|
983
983
|
'explain.md', 'visual-plan.md', 'tailscale-serve.md',
|
|
984
984
|
'README.md', 'AGENTS.md', 'COMMANDS.md', 'INSTRUCTIONS.md',
|
package/bizar-dash/tests/{no-agent-browser.node.test.mjs → no-browser-harness.node.test.mjs}
RENAMED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* no-
|
|
2
|
+
* no-browser-harness.node.test.mjs — regression test for the v6.0.0 migration.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* https://github.com/
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* v6.0.0 replaces the v5.x `browser-harness` (Python tool from
|
|
5
|
+
* https://github.com/browser-use/browser-harness) with `agent-browser`
|
|
6
|
+
* (native Rust CLI from vercel-labs, ~38K★ — https://github.com/vercel-labs/agent-browser).
|
|
7
|
+
*
|
|
8
|
+
* This test ensures no `browser-harness` references leak back into the
|
|
9
|
+
* shipped config, the install/bootstrap scripts, or the dashboard code.
|
|
9
10
|
*
|
|
10
11
|
* Allowed exceptions:
|
|
11
|
-
* - .bizar/AGENTS_SELF_IMPROVEMENT.md (historical rule entry
|
|
12
|
-
* the v3.20.7 migration)
|
|
12
|
+
* - .bizar/AGENTS_SELF_IMPROVEMENT.md (historical rule entry)
|
|
13
13
|
* - CHANGELOG.md (historical release notes)
|
|
14
|
+
* - docs/migration-guide.md (documents the v5.x → v6.0.0 migration)
|
|
14
15
|
*
|
|
15
|
-
* Run with: node --test tests/no-
|
|
16
|
+
* Run with: node --test tests/no-browser-harness.node.test.mjs
|
|
16
17
|
*/
|
|
17
18
|
import { describe, it } from 'node:test';
|
|
18
19
|
import assert from 'node:assert/strict';
|
|
@@ -24,6 +25,7 @@ const REPO = resolve(import.meta.dirname, '..', '..');
|
|
|
24
25
|
const SCAN_DIRS = [
|
|
25
26
|
'config',
|
|
26
27
|
'cli',
|
|
28
|
+
'plugins',
|
|
27
29
|
'bizar-dash/src',
|
|
28
30
|
'install.sh',
|
|
29
31
|
];
|
|
@@ -31,10 +33,13 @@ const SCAN_EXTENSIONS = ['.mjs', '.ts', '.tsx', '.json', '.sh', '.md', '.mdx', '
|
|
|
31
33
|
const ALLOW_FILES = new Set([
|
|
32
34
|
'.bizar/AGENTS_SELF_IMPROVEMENT.md', // historical rule entry
|
|
33
35
|
'CHANGELOG.md', // historical release notes
|
|
36
|
+
'docs/migration-guide.md', // documents the migration rationale
|
|
37
|
+
'MILESTONES.md', // strategic roadmap (references legacy)
|
|
38
|
+
'IMPLEMENTATION_PLAN.md', // tactical plan (references legacy)
|
|
34
39
|
]);
|
|
35
40
|
const PATTERNS = [
|
|
36
|
-
/
|
|
37
|
-
/
|
|
41
|
+
/browser[-_]?harness/i, // browser-harness, browser_harness, browserHarness
|
|
42
|
+
/browser_harness_/i, // browser_harness_open etc.
|
|
38
43
|
];
|
|
39
44
|
|
|
40
45
|
function isAllowed(relPath) {
|
|
@@ -49,7 +54,6 @@ function* walkFiles(root) {
|
|
|
49
54
|
return;
|
|
50
55
|
}
|
|
51
56
|
if (!stat.isDirectory()) return;
|
|
52
|
-
// Skip noise
|
|
53
57
|
if (root.includes('node_modules')) return;
|
|
54
58
|
if (root.includes('.git')) return;
|
|
55
59
|
for (const entry of readdirSync(root)) {
|
|
@@ -57,7 +61,7 @@ function* walkFiles(root) {
|
|
|
57
61
|
}
|
|
58
62
|
}
|
|
59
63
|
|
|
60
|
-
describe('no
|
|
64
|
+
describe('no browser-harness references in shipped code (v6.0.0+ uses agent-browser)', () => {
|
|
61
65
|
const violations = [];
|
|
62
66
|
|
|
63
67
|
for (const target of SCAN_DIRS) {
|
|
@@ -80,19 +84,15 @@ describe('no agent-browser references in shipped code', () => {
|
|
|
80
84
|
}
|
|
81
85
|
}
|
|
82
86
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
});
|
|
87
|
+
if (violations.length > 0) {
|
|
88
|
+
const lines = violations.map((v) => ` - ${v.file}: matched "${v.match}"`);
|
|
89
|
+
assert.fail(
|
|
90
|
+
`Found ${violations.length} browser-harness reference(s) in shipped code:\n${lines.join('\n')}\n` +
|
|
91
|
+
`Use agent-browser instead. See docs/migration-guide.md.`
|
|
92
|
+
);
|
|
93
|
+
}
|
|
91
94
|
|
|
92
|
-
it('
|
|
93
|
-
|
|
94
|
-
// historical references that should be preserved).
|
|
95
|
-
assert.ok(ALLOW_FILES.size >= 2,
|
|
96
|
-
'expected ALLOW_FILES to include at least AGENTS_SELF_IMPROVEMENT.md + CHANGELOG.md');
|
|
95
|
+
it('has no browser-harness references in shipped config / code / install scripts', () => {
|
|
96
|
+
assert.equal(violations.length, 0);
|
|
97
97
|
});
|
|
98
98
|
});
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# cli/agent-browser-up.sh — install/launch agent-browser for Cline.
|
|
4
|
+
# v6.0.0 — Replaces browser-harness (Python, v3.20.7-v5.6.0) with
|
|
5
|
+
# agent-browser (native Rust CLI from vercel-labs, ~38K★).
|
|
6
|
+
#
|
|
7
|
+
# agent-browser is a thin CLI wrapper around Chrome for Testing that
|
|
8
|
+
# gives agents access to:
|
|
9
|
+
# - 100+ typed CLI commands (open, snapshot, click, fill, screenshot, …)
|
|
10
|
+
# - Native MCP stdio server (`agent-browser mcp`)
|
|
11
|
+
# - Self-healing snapshot-based element detection
|
|
12
|
+
# - Plugins (vault, recorder, …)
|
|
13
|
+
# - Vercel AI SDK + AI Gateway integration (natural-language `chat`)
|
|
14
|
+
#
|
|
15
|
+
# Install: npm install -g agent-browser
|
|
16
|
+
# agent-browser install # downloads Chrome for Testing
|
|
17
|
+
#
|
|
18
|
+
# This script ensures the daemon is up before Bizar agents try to
|
|
19
|
+
# drive the browser. Idempotent: re-running is a no-op if already up.
|
|
20
|
+
#
|
|
21
|
+
# Usage:
|
|
22
|
+
# cli/agent-browser-up.sh # start if not running
|
|
23
|
+
# cli/agent-browser-up.sh status # print status
|
|
24
|
+
# cli/agent-browser-up.sh stop # kill daemon
|
|
25
|
+
# cli/agent-browser-up.sh restart # stop + start
|
|
26
|
+
# cli/agent-browser-up.sh install # install + bootstrap
|
|
27
|
+
# cli/agent-browser-up.sh doctor # run agent-browser doctor
|
|
28
|
+
#
|
|
29
|
+
# Environment overrides:
|
|
30
|
+
# AB_PROFILE — user-data-dir (default: ~/.agent-browser/profile)
|
|
31
|
+
# AGENT_BROWSER_API_KEY — for natural-language chat
|
|
32
|
+
#
|
|
33
|
+
# Exit codes:
|
|
34
|
+
# 0 started / already running / status clean
|
|
35
|
+
# 1 failed to start (missing binary, port busy, etc.)
|
|
36
|
+
#
|
|
37
|
+
set -euo pipefail
|
|
38
|
+
|
|
39
|
+
AB_BIN="${AB_BIN:-$(command -v agent-browser || true)}"
|
|
40
|
+
AB_DAEMON_HOST="127.0.0.1"
|
|
41
|
+
AB_DAEMON_PORT="${AB_DAEMON_PORT:-9223}"
|
|
42
|
+
AB_PROFILE="${AB_PROFILE:-$HOME/.agent-browser/profile}"
|
|
43
|
+
|
|
44
|
+
log() { echo "[agent-browser-up] $*" >&2; }
|
|
45
|
+
fail() { log "FAIL: $*"; exit 1; }
|
|
46
|
+
|
|
47
|
+
ensure_binary() {
|
|
48
|
+
if [ -z "$AB_BIN" ] || ! [ -x "$AB_BIN" ]; then
|
|
49
|
+
log "agent-browser not on PATH. Installing via npm..."
|
|
50
|
+
command -v npm >/dev/null || fail "npm not found — install Node.js 24+ first"
|
|
51
|
+
npm install -g agent-browser
|
|
52
|
+
AB_BIN="$(command -v agent-browser)"
|
|
53
|
+
[ -x "$AB_BIN" ] || fail "agent-browser install failed"
|
|
54
|
+
fi
|
|
55
|
+
log "agent-browser binary: $AB_BIN"
|
|
56
|
+
log "version: $($AB_BIN --version 2>/dev/null || echo 'unknown')"
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
ensure_chrome() {
|
|
60
|
+
if [ -d "$AB_PROFILE" ] && [ -f "$AB_PROFILE/SingletonLock" ]; then
|
|
61
|
+
log "Chrome profile already exists: $AB_PROFILE"
|
|
62
|
+
return 0
|
|
63
|
+
fi
|
|
64
|
+
log "Bootstrapping Chrome for Testing via agent-browser install"
|
|
65
|
+
$AB_BIN install --silent || true
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
is_daemon_running() {
|
|
69
|
+
$AB_BIN status --quiet 2>/dev/null && return 0
|
|
70
|
+
# Fallback: check the daemon HTTP endpoint
|
|
71
|
+
curl -fsS --max-time 2 "http://${AB_DAEMON_HOST}:${AB_DAEMON_PORT}/json/version" >/dev/null 2>&1
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
start_daemon() {
|
|
75
|
+
log "Starting agent-browser daemon (profile: $AB_PROFILE, port: $AB_DAEMON_PORT)..."
|
|
76
|
+
mkdir -p "$AB_PROFILE"
|
|
77
|
+
|
|
78
|
+
# Spawn the daemon detached so it survives parent shell exit
|
|
79
|
+
setsid nohup "$AB_BIN" serve \
|
|
80
|
+
--port "$AB_DAEMON_PORT" \
|
|
81
|
+
--profile "$AB_PROFILE" \
|
|
82
|
+
--headless \
|
|
83
|
+
>"$AB_PROFILE/daemon.log" 2>&1 < /dev/null &
|
|
84
|
+
local pid=$!
|
|
85
|
+
echo $pid > "$AB_PROFILE/daemon.pid"
|
|
86
|
+
disown $pid 2>/dev/null || true
|
|
87
|
+
|
|
88
|
+
# Wait for the daemon to bind
|
|
89
|
+
local retries=30
|
|
90
|
+
while [ $retries -gt 0 ]; do
|
|
91
|
+
if curl -fsS --max-time 2 "http://${AB_DAEMON_HOST}:${AB_DAEMON_PORT}/json/version" >/dev/null 2>&1; then
|
|
92
|
+
log "agent-browser daemon is up (pid $pid)"
|
|
93
|
+
return 0
|
|
94
|
+
fi
|
|
95
|
+
sleep 1
|
|
96
|
+
retries=$((retries - 1))
|
|
97
|
+
done
|
|
98
|
+
fail "agent-browser daemon did not bind to ${AB_DAEMON_HOST}:${AB_DAEMON_PORT}"
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
stop_daemon() {
|
|
102
|
+
local pidfile="$AB_PROFILE/daemon.pid"
|
|
103
|
+
if [ -f "$pidfile" ]; then
|
|
104
|
+
local pid
|
|
105
|
+
pid="$(cat "$pidfile" 2>/dev/null || true)"
|
|
106
|
+
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
|
|
107
|
+
log "Stopping agent-browser daemon (pid $pid)"
|
|
108
|
+
kill "$pid" 2>/dev/null || true
|
|
109
|
+
sleep 1
|
|
110
|
+
kill -9 "$pid" 2>/dev/null || true
|
|
111
|
+
fi
|
|
112
|
+
rm -f "$pidfile"
|
|
113
|
+
fi
|
|
114
|
+
# Belt-and-braces: kill any orphan agent-browser processes
|
|
115
|
+
pkill -f 'agent-browser serve' 2>/dev/null || true
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
print_status() {
|
|
119
|
+
if is_daemon_running; then
|
|
120
|
+
echo "agent-browser: RUNNING (http://${AB_DAEMON_HOST}:${AB_DAEMON_PORT})"
|
|
121
|
+
$AB_BIN doctor 2>&1 | tail -20 || true
|
|
122
|
+
else
|
|
123
|
+
echo "agent-browser: STOPPED"
|
|
124
|
+
echo "Start with: cli/agent-browser-up.sh start"
|
|
125
|
+
fi
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
case "${1:-start}" in
|
|
129
|
+
start) ensure_binary; ensure_chrome; is_daemon_running && { log "already running"; exit 0; }; start_daemon ;;
|
|
130
|
+
stop) stop_daemon ;;
|
|
131
|
+
restart) stop_daemon; sleep 1; ensure_binary; ensure_chrome; start_daemon ;;
|
|
132
|
+
status) ensure_binary; print_status ;;
|
|
133
|
+
doctor) ensure_binary; $AB_BIN doctor ;;
|
|
134
|
+
install) ensure_binary; ensure_chrome; $AB_BIN install ;;
|
|
135
|
+
*) fail "unknown command: $1 (use start|stop|restart|status|doctor|install)" ;;
|
|
136
|
+
esac
|