arise-browser 0.3.0 → 0.4.0
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/README.md +4 -4
- package/deploy/neko/CONTEXT.md +2 -2
- package/deploy/neko/arise-browser.service +1 -1
- package/deploy/neko/setup.sh +2 -2
- package/dist/bin/arise-browser.d.ts +9 -19
- package/dist/bin/arise-browser.d.ts.map +1 -1
- package/dist/bin/arise-browser.js +206 -192
- package/dist/bin/arise-browser.js.map +1 -1
- package/dist/bin/cli.d.ts +9 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +332 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/src/server/routes/health.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/plugin/openclaw.plugin.json +1 -1
- package/skill/arise-browser/SKILL.md +71 -120
- package/skill/arise-browser/references/api.md +1 -1
package/dist/bin/cli.js
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* AriseBrowser CLI — Agent-friendly subcommands for browser control.
|
|
4
|
+
*
|
|
5
|
+
* Each subcommand calls the local HTTP server and outputs plain text.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, writeFileSync, mkdirSync, unlinkSync } from "node:fs";
|
|
8
|
+
import { homedir } from "node:os";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { spawn } from "node:child_process";
|
|
11
|
+
const STATE_DIR = join(homedir(), ".arise-browser");
|
|
12
|
+
const PID_FILE = join(STATE_DIR, "server.pid");
|
|
13
|
+
const PORT_FILE = join(STATE_DIR, "server.port");
|
|
14
|
+
const DEFAULT_PORT = 16473;
|
|
15
|
+
function resolvePort() {
|
|
16
|
+
const envPort = process.env.ARISE_BROWSER_PORT || process.env.BRIDGE_PORT;
|
|
17
|
+
if (envPort)
|
|
18
|
+
return parseInt(envPort, 10);
|
|
19
|
+
try {
|
|
20
|
+
const stored = readFileSync(PORT_FILE, "utf-8").trim();
|
|
21
|
+
if (stored)
|
|
22
|
+
return parseInt(stored, 10);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
// file doesn't exist
|
|
26
|
+
}
|
|
27
|
+
return DEFAULT_PORT;
|
|
28
|
+
}
|
|
29
|
+
function baseUrl() {
|
|
30
|
+
return `http://127.0.0.1:${resolvePort()}`;
|
|
31
|
+
}
|
|
32
|
+
async function fetchJson(path, init) {
|
|
33
|
+
const url = `${baseUrl()}${path}`;
|
|
34
|
+
const res = await fetch(url, init);
|
|
35
|
+
if (!res.ok) {
|
|
36
|
+
const text = await res.text().catch(() => "");
|
|
37
|
+
let msg;
|
|
38
|
+
try {
|
|
39
|
+
const json = JSON.parse(text);
|
|
40
|
+
msg = json.error || json.message || text;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
msg = text;
|
|
44
|
+
}
|
|
45
|
+
throw new Error(`${res.status}: ${msg}`);
|
|
46
|
+
}
|
|
47
|
+
const ct = res.headers.get("content-type") || "";
|
|
48
|
+
if (ct.includes("text/plain")) {
|
|
49
|
+
return { __text: await res.text() };
|
|
50
|
+
}
|
|
51
|
+
if (ct.includes("image/")) {
|
|
52
|
+
return { __buffer: Buffer.from(await res.arrayBuffer()) };
|
|
53
|
+
}
|
|
54
|
+
return res.json();
|
|
55
|
+
}
|
|
56
|
+
function die(msg) {
|
|
57
|
+
process.stderr.write(msg + "\n");
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
// ── Subcommands ──────────────────────────────────────────────
|
|
61
|
+
async function cmdHealth() {
|
|
62
|
+
try {
|
|
63
|
+
const data = await fetchJson("/health");
|
|
64
|
+
if (data.status === "ok" && data.connected) {
|
|
65
|
+
console.log("ok");
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
console.log(`status=${data.status} connected=${data.connected}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
console.log("not running");
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function cmdStart(args) {
|
|
77
|
+
// Check if already running
|
|
78
|
+
try {
|
|
79
|
+
const data = await fetchJson("/health");
|
|
80
|
+
if (data.status === "ok") {
|
|
81
|
+
console.log(`Already running on port ${resolvePort()}`);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// not running, continue
|
|
87
|
+
}
|
|
88
|
+
const port = resolvePort();
|
|
89
|
+
// Build server args — pass through all flags + force port
|
|
90
|
+
const serverArgs = ["--port", String(port)];
|
|
91
|
+
for (const arg of args) {
|
|
92
|
+
// Skip subcommand name "start"
|
|
93
|
+
if (arg === "start")
|
|
94
|
+
continue;
|
|
95
|
+
serverArgs.push(arg);
|
|
96
|
+
}
|
|
97
|
+
// Find the server entry point
|
|
98
|
+
const binPath = new URL("./arise-browser.js", import.meta.url).pathname;
|
|
99
|
+
mkdirSync(STATE_DIR, { recursive: true });
|
|
100
|
+
// Spawn as detached daemon
|
|
101
|
+
const child = spawn(process.execPath, [binPath, ...serverArgs], {
|
|
102
|
+
detached: true,
|
|
103
|
+
stdio: ["ignore", "ignore", "ignore"],
|
|
104
|
+
env: { ...process.env, ARISE_BROWSER_CLI_SERVER: "1" },
|
|
105
|
+
});
|
|
106
|
+
child.unref();
|
|
107
|
+
if (!child.pid) {
|
|
108
|
+
die("Failed to start server process");
|
|
109
|
+
}
|
|
110
|
+
writeFileSync(PID_FILE, String(child.pid));
|
|
111
|
+
writeFileSync(PORT_FILE, String(port));
|
|
112
|
+
// Poll health until ready (max 120s)
|
|
113
|
+
const deadline = Date.now() + 120_000;
|
|
114
|
+
let ready = false;
|
|
115
|
+
while (Date.now() < deadline) {
|
|
116
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
117
|
+
try {
|
|
118
|
+
const data = await fetchJson("/health");
|
|
119
|
+
if (data.status === "ok" && data.connected) {
|
|
120
|
+
ready = true;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// not ready yet
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (!ready) {
|
|
129
|
+
die("Server started but did not become ready within 120s");
|
|
130
|
+
}
|
|
131
|
+
console.log(`Server ready on port ${port}`);
|
|
132
|
+
}
|
|
133
|
+
async function cmdStop() {
|
|
134
|
+
// Kill server process
|
|
135
|
+
let killed = false;
|
|
136
|
+
try {
|
|
137
|
+
const pid = parseInt(readFileSync(PID_FILE, "utf-8").trim(), 10);
|
|
138
|
+
if (pid > 0) {
|
|
139
|
+
try {
|
|
140
|
+
process.kill(pid, "SIGTERM");
|
|
141
|
+
killed = true;
|
|
142
|
+
}
|
|
143
|
+
catch (e) {
|
|
144
|
+
if (e.code !== "ESRCH")
|
|
145
|
+
throw e;
|
|
146
|
+
// already dead
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
// no PID file
|
|
152
|
+
}
|
|
153
|
+
// Try to stop Docker container
|
|
154
|
+
try {
|
|
155
|
+
const containerName = process.env.ARISE_BROWSER_CONTAINER_NAME || "arise-neko";
|
|
156
|
+
const docker = spawn("docker", ["rm", "-f", containerName], {
|
|
157
|
+
stdio: ["ignore", "ignore", "ignore"],
|
|
158
|
+
});
|
|
159
|
+
await new Promise((resolve) => docker.on("close", () => resolve()));
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// docker not available or no container
|
|
163
|
+
}
|
|
164
|
+
// Clean up state files
|
|
165
|
+
for (const f of [PID_FILE, PORT_FILE]) {
|
|
166
|
+
try {
|
|
167
|
+
unlinkSync(f);
|
|
168
|
+
}
|
|
169
|
+
catch { /* ignore */ }
|
|
170
|
+
}
|
|
171
|
+
console.log("Stopped");
|
|
172
|
+
}
|
|
173
|
+
async function cmdOpen(args) {
|
|
174
|
+
const url = args[0];
|
|
175
|
+
if (!url)
|
|
176
|
+
die("Usage: arise-browser open <url>");
|
|
177
|
+
const data = await fetchJson("/navigate", {
|
|
178
|
+
method: "POST",
|
|
179
|
+
headers: { "Content-Type": "application/json" },
|
|
180
|
+
body: JSON.stringify({ url }),
|
|
181
|
+
});
|
|
182
|
+
console.log(`Navigated to ${data.url || url}`);
|
|
183
|
+
}
|
|
184
|
+
async function cmdSnap() {
|
|
185
|
+
const data = await fetchJson("/snapshot?format=yaml");
|
|
186
|
+
if (data.__text) {
|
|
187
|
+
console.log(data.__text);
|
|
188
|
+
}
|
|
189
|
+
else if (data.snapshot) {
|
|
190
|
+
console.log(data.snapshot);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
console.log(JSON.stringify(data, null, 2));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
async function cmdClick(args) {
|
|
197
|
+
const ref = args[0];
|
|
198
|
+
if (!ref)
|
|
199
|
+
die("Usage: arise-browser click <ref>");
|
|
200
|
+
await fetchJson("/action", {
|
|
201
|
+
method: "POST",
|
|
202
|
+
headers: { "Content-Type": "application/json" },
|
|
203
|
+
body: JSON.stringify({ type: "click", ref }),
|
|
204
|
+
});
|
|
205
|
+
console.log(`Clicked ${ref}`);
|
|
206
|
+
}
|
|
207
|
+
async function cmdType(args) {
|
|
208
|
+
const ref = args[0];
|
|
209
|
+
const text = args.slice(1).join(" ");
|
|
210
|
+
if (!ref || !text)
|
|
211
|
+
die("Usage: arise-browser type <ref> <text>");
|
|
212
|
+
await fetchJson("/action", {
|
|
213
|
+
method: "POST",
|
|
214
|
+
headers: { "Content-Type": "application/json" },
|
|
215
|
+
body: JSON.stringify({ type: "type", ref, text }),
|
|
216
|
+
});
|
|
217
|
+
console.log(`Typed '${text}' into ${ref}`);
|
|
218
|
+
}
|
|
219
|
+
async function cmdSelect(args) {
|
|
220
|
+
const ref = args[0];
|
|
221
|
+
const value = args.slice(1).join(" ");
|
|
222
|
+
if (!ref || !value)
|
|
223
|
+
die("Usage: arise-browser select <ref> <value>");
|
|
224
|
+
await fetchJson("/action", {
|
|
225
|
+
method: "POST",
|
|
226
|
+
headers: { "Content-Type": "application/json" },
|
|
227
|
+
body: JSON.stringify({ type: "select", ref, value }),
|
|
228
|
+
});
|
|
229
|
+
console.log(`Selected '${value}' on ${ref}`);
|
|
230
|
+
}
|
|
231
|
+
async function cmdPress(args) {
|
|
232
|
+
const key = args[0];
|
|
233
|
+
if (!key)
|
|
234
|
+
die("Usage: arise-browser press <key>");
|
|
235
|
+
await fetchJson("/action", {
|
|
236
|
+
method: "POST",
|
|
237
|
+
headers: { "Content-Type": "application/json" },
|
|
238
|
+
body: JSON.stringify({ type: "press_key", key }),
|
|
239
|
+
});
|
|
240
|
+
console.log(`Pressed ${key}`);
|
|
241
|
+
}
|
|
242
|
+
async function cmdScroll(args) {
|
|
243
|
+
const direction = args[0];
|
|
244
|
+
if (!direction)
|
|
245
|
+
die("Usage: arise-browser scroll <up|down|left|right> [amount]");
|
|
246
|
+
const amount = args[1] ? parseInt(args[1], 10) : undefined;
|
|
247
|
+
const body = { type: "scroll", direction };
|
|
248
|
+
if (amount !== undefined && !Number.isNaN(amount)) {
|
|
249
|
+
body.amount = amount;
|
|
250
|
+
}
|
|
251
|
+
await fetchJson("/action", {
|
|
252
|
+
method: "POST",
|
|
253
|
+
headers: { "Content-Type": "application/json" },
|
|
254
|
+
body: JSON.stringify(body),
|
|
255
|
+
});
|
|
256
|
+
console.log(`Scrolled ${direction}${amount ? ` ${amount}px` : ""}`);
|
|
257
|
+
}
|
|
258
|
+
async function cmdScreenshot(args) {
|
|
259
|
+
const file = args[0] || "screenshot.jpg";
|
|
260
|
+
const res = await fetch(`${baseUrl()}/screenshot?raw=true`);
|
|
261
|
+
if (!res.ok) {
|
|
262
|
+
die(`Screenshot failed: ${res.status}`);
|
|
263
|
+
}
|
|
264
|
+
const buffer = Buffer.from(await res.arrayBuffer());
|
|
265
|
+
writeFileSync(file, buffer);
|
|
266
|
+
console.log(file);
|
|
267
|
+
}
|
|
268
|
+
async function cmdTabs() {
|
|
269
|
+
const data = await fetchJson("/tabs");
|
|
270
|
+
const tabs = data.tabs || [];
|
|
271
|
+
for (const tab of tabs) {
|
|
272
|
+
const active = tab.is_current ? " *" : "";
|
|
273
|
+
const id = tab.tab_id || tab.tabId || tab.id || "";
|
|
274
|
+
console.log(`${id} ${tab.title || ""} ${tab.url || ""}${active}`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// ── Dispatch ─────────────────────────────────────────────────
|
|
278
|
+
const COMMANDS = {
|
|
279
|
+
start: cmdStart,
|
|
280
|
+
stop: () => cmdStop(),
|
|
281
|
+
open: cmdOpen,
|
|
282
|
+
snap: () => cmdSnap(),
|
|
283
|
+
click: cmdClick,
|
|
284
|
+
type: cmdType,
|
|
285
|
+
select: cmdSelect,
|
|
286
|
+
press: cmdPress,
|
|
287
|
+
scroll: cmdScroll,
|
|
288
|
+
screenshot: cmdScreenshot,
|
|
289
|
+
tabs: () => cmdTabs(),
|
|
290
|
+
health: () => cmdHealth(),
|
|
291
|
+
};
|
|
292
|
+
export const KNOWN_COMMANDS = Object.keys(COMMANDS);
|
|
293
|
+
export async function run() {
|
|
294
|
+
const argv = process.argv.slice(2);
|
|
295
|
+
const cmd = argv[0];
|
|
296
|
+
if (!cmd || !COMMANDS[cmd]) {
|
|
297
|
+
console.log(`Usage: arise-browser <command> [args]
|
|
298
|
+
|
|
299
|
+
Commands:
|
|
300
|
+
start Start the browser server (daemon)
|
|
301
|
+
stop Stop the server and clean up
|
|
302
|
+
open <url> Navigate to URL
|
|
303
|
+
snap Take page snapshot (YAML)
|
|
304
|
+
click <ref> Click element by ref
|
|
305
|
+
type <ref> <text> Type text into element
|
|
306
|
+
select <ref> <value> Select dropdown value
|
|
307
|
+
press <key> Press keyboard key
|
|
308
|
+
scroll <dir> [amount] Scroll page (up/down/left/right)
|
|
309
|
+
screenshot [file] Save screenshot to file
|
|
310
|
+
tabs List open tabs
|
|
311
|
+
health Check server status
|
|
312
|
+
|
|
313
|
+
Options for 'start':
|
|
314
|
+
--virtual-display Enable Docker virtual display
|
|
315
|
+
--port, -p <port> Server port (default: ${DEFAULT_PORT})
|
|
316
|
+
--host <host> Bind address (default: 127.0.0.1)
|
|
317
|
+
--headless / --no-headless
|
|
318
|
+
--cdp <url> CDP endpoint URL
|
|
319
|
+
--profile <dir> Browser profile directory
|
|
320
|
+
`);
|
|
321
|
+
process.exit(cmd ? 1 : 0);
|
|
322
|
+
}
|
|
323
|
+
const handler = COMMANDS[cmd];
|
|
324
|
+
const cmdArgs = argv.slice(1);
|
|
325
|
+
try {
|
|
326
|
+
await handler(cmdArgs);
|
|
327
|
+
}
|
|
328
|
+
catch (e) {
|
|
329
|
+
die(e.message || String(e));
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":"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"}
|