browserclaw 0.2.5 → 0.2.7
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 +5 -3
- package/dist/index.cjs +75 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +75 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
<h2 align="center">🦞 BrowserClaw — Standalone OpenClaw browser module</h1>
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
<p align="center">
|
|
4
|
+
<a href="https://www.npmjs.com/package/browserclaw"><img src="https://img.shields.io/npm/v/browserclaw.svg" alt="npm version" /></a>
|
|
5
|
+
<a href="./LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT" /></a>
|
|
6
|
+
</p>
|
|
5
7
|
|
|
6
8
|
Extracted and refined from [OpenClaw](https://github.com/openclaw/openclaw)'s browser automation module. A standalone, typed library for AI-friendly browser control with **snapshot + ref targeting** — no CSS selectors, no XPath, no vision, just numbered refs that map to interactive elements.
|
|
7
9
|
|
package/dist/index.cjs
CHANGED
|
@@ -408,7 +408,8 @@ async function launchChrome(opts = {}) {
|
|
|
408
408
|
args.push("--no-sandbox", "--disable-setuid-sandbox");
|
|
409
409
|
}
|
|
410
410
|
if (process.platform === "linux") args.push("--disable-dev-shm-usage");
|
|
411
|
-
|
|
411
|
+
const extraArgs = Array.isArray(opts.chromeArgs) ? opts.chromeArgs.filter((a) => typeof a === "string" && a.trim().length > 0) : [];
|
|
412
|
+
if (extraArgs.length) args.push(...extraArgs);
|
|
412
413
|
args.push("about:blank");
|
|
413
414
|
return child_process.spawn(exe.path, args, {
|
|
414
415
|
stdio: "pipe",
|
|
@@ -1405,7 +1406,76 @@ function assertSafeOutputPath(path2, allowedRoots) {
|
|
|
1405
1406
|
}
|
|
1406
1407
|
}
|
|
1407
1408
|
}
|
|
1409
|
+
function expandIPv6(ip) {
|
|
1410
|
+
let normalized = ip;
|
|
1411
|
+
const v4Match = normalized.match(/^(.+:)(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/);
|
|
1412
|
+
if (v4Match) {
|
|
1413
|
+
const octets = v4Match[2].split(".").map(Number);
|
|
1414
|
+
if (octets.some((o) => o > 255)) return null;
|
|
1415
|
+
const hexHi = (octets[0] << 8 | octets[1]).toString(16).padStart(4, "0");
|
|
1416
|
+
const hexLo = (octets[2] << 8 | octets[3]).toString(16).padStart(4, "0");
|
|
1417
|
+
normalized = v4Match[1] + hexHi + ":" + hexLo;
|
|
1418
|
+
}
|
|
1419
|
+
const halves = normalized.split("::");
|
|
1420
|
+
if (halves.length > 2) return null;
|
|
1421
|
+
if (halves.length === 2) {
|
|
1422
|
+
const left = halves[0] !== "" ? halves[0].split(":") : [];
|
|
1423
|
+
const right = halves[1] !== "" ? halves[1].split(":") : [];
|
|
1424
|
+
const needed = 8 - left.length - right.length;
|
|
1425
|
+
if (needed < 0) return null;
|
|
1426
|
+
const groups2 = [...left, ...Array(needed).fill("0"), ...right];
|
|
1427
|
+
if (groups2.length !== 8) return null;
|
|
1428
|
+
return groups2.map((g) => g.padStart(4, "0")).join(":");
|
|
1429
|
+
}
|
|
1430
|
+
const groups = normalized.split(":");
|
|
1431
|
+
if (groups.length !== 8) return null;
|
|
1432
|
+
return groups.map((g) => g.padStart(4, "0")).join(":");
|
|
1433
|
+
}
|
|
1434
|
+
function hexToIPv4(hiHex, loHex) {
|
|
1435
|
+
const hi = parseInt(hiHex, 16);
|
|
1436
|
+
const lo = parseInt(loHex, 16);
|
|
1437
|
+
return `${hi >> 8 & 255}.${hi & 255}.${lo >> 8 & 255}.${lo & 255}`;
|
|
1438
|
+
}
|
|
1439
|
+
function extractEmbeddedIPv4(lower) {
|
|
1440
|
+
if (lower.startsWith("::ffff:")) {
|
|
1441
|
+
return lower.slice(7);
|
|
1442
|
+
}
|
|
1443
|
+
const expanded = expandIPv6(lower);
|
|
1444
|
+
if (expanded === null) return "";
|
|
1445
|
+
const groups = expanded.split(":");
|
|
1446
|
+
if (groups.length !== 8) return "";
|
|
1447
|
+
if (groups[0] === "0064" && groups[1] === "ff9b" && groups[2] === "0000" && groups[3] === "0000" && groups[4] === "0000" && groups[5] === "0000") {
|
|
1448
|
+
return hexToIPv4(groups[6], groups[7]);
|
|
1449
|
+
}
|
|
1450
|
+
if (groups[0] === "0064" && groups[1] === "ff9b" && groups[2] === "0001") {
|
|
1451
|
+
return hexToIPv4(groups[6], groups[7]);
|
|
1452
|
+
}
|
|
1453
|
+
if (groups[0] === "2002") {
|
|
1454
|
+
return hexToIPv4(groups[1], groups[2]);
|
|
1455
|
+
}
|
|
1456
|
+
if (groups[0] === "2001" && groups[1] === "0000") {
|
|
1457
|
+
const hiXored = (parseInt(groups[6], 16) ^ 65535).toString(16).padStart(4, "0");
|
|
1458
|
+
const loXored = (parseInt(groups[7], 16) ^ 65535).toString(16).padStart(4, "0");
|
|
1459
|
+
return hexToIPv4(hiXored, loXored);
|
|
1460
|
+
}
|
|
1461
|
+
return null;
|
|
1462
|
+
}
|
|
1463
|
+
function isStrictDecimalOctet(part) {
|
|
1464
|
+
if (!/^[0-9]+$/.test(part)) return false;
|
|
1465
|
+
const n = parseInt(part, 10);
|
|
1466
|
+
if (n < 0 || n > 255) return false;
|
|
1467
|
+
if (String(n) !== part) return false;
|
|
1468
|
+
return true;
|
|
1469
|
+
}
|
|
1470
|
+
function isUnsupportedIPv4Literal(ip) {
|
|
1471
|
+
if (/^[0-9]+$/.test(ip)) return true;
|
|
1472
|
+
const parts = ip.split(".");
|
|
1473
|
+
if (parts.length !== 4) return true;
|
|
1474
|
+
if (!parts.every(isStrictDecimalOctet)) return true;
|
|
1475
|
+
return false;
|
|
1476
|
+
}
|
|
1408
1477
|
function isInternalIP(ip) {
|
|
1478
|
+
if (!ip.includes(":") && isUnsupportedIPv4Literal(ip)) return true;
|
|
1409
1479
|
if (/^127\./.test(ip)) return true;
|
|
1410
1480
|
if (/^10\./.test(ip)) return true;
|
|
1411
1481
|
if (/^172\.(1[6-9]|2\d|3[01])\./.test(ip)) return true;
|
|
@@ -1417,9 +1487,10 @@ function isInternalIP(ip) {
|
|
|
1417
1487
|
if (lower === "::1") return true;
|
|
1418
1488
|
if (lower.startsWith("fe80:")) return true;
|
|
1419
1489
|
if (lower.startsWith("fc") || lower.startsWith("fd")) return true;
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1490
|
+
const embedded = extractEmbeddedIPv4(lower);
|
|
1491
|
+
if (embedded !== null) {
|
|
1492
|
+
if (embedded === "") return true;
|
|
1493
|
+
return isInternalIP(embedded);
|
|
1423
1494
|
}
|
|
1424
1495
|
return false;
|
|
1425
1496
|
}
|