@ulpi/browse 1.0.2 → 1.0.3
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/dist/{browse.mjs → browse.cjs} +109 -101
- package/package.json +3 -3
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
const __import_meta_url = require("url").pathToFileURL(__filename).href;
|
|
3
|
+
"use strict";
|
|
2
4
|
var __create = Object.create;
|
|
3
5
|
var __defProp = Object.defineProperty;
|
|
4
6
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
7
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
8
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
9
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
9
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
10
|
-
}) : x)(function(x) {
|
|
11
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
12
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
13
|
-
});
|
|
14
10
|
var __esm = (fn, res) => function __init() {
|
|
15
11
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
16
12
|
};
|
|
17
|
-
var __commonJS = (cb, mod) => function
|
|
13
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
18
14
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
19
15
|
};
|
|
20
16
|
var __export = (target, all) => {
|
|
@@ -38,6 +34,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
38
34
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
39
35
|
mod
|
|
40
36
|
));
|
|
37
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
41
38
|
|
|
42
39
|
// src/constants.ts
|
|
43
40
|
var BROWSE_TIMEOUT, DEFAULTS;
|
|
@@ -68,9 +65,6 @@ var chrome_discover_exports = {};
|
|
|
68
65
|
__export(chrome_discover_exports, {
|
|
69
66
|
discoverChrome: () => discoverChrome
|
|
70
67
|
});
|
|
71
|
-
import * as os from "os";
|
|
72
|
-
import * as fs2 from "fs";
|
|
73
|
-
import * as path2 from "path";
|
|
74
68
|
async function fetchWsUrl(port) {
|
|
75
69
|
try {
|
|
76
70
|
const res = await fetch(`http://127.0.0.1:${port}/json/version`, {
|
|
@@ -108,10 +102,13 @@ async function discoverChrome() {
|
|
|
108
102
|
}
|
|
109
103
|
return null;
|
|
110
104
|
}
|
|
111
|
-
var PROFILE_PATHS, PROBE_PORTS;
|
|
105
|
+
var os, fs2, path2, PROFILE_PATHS, PROBE_PORTS;
|
|
112
106
|
var init_chrome_discover = __esm({
|
|
113
107
|
"src/chrome-discover.ts"() {
|
|
114
108
|
"use strict";
|
|
109
|
+
os = __toESM(require("os"), 1);
|
|
110
|
+
fs2 = __toESM(require("fs"), 1);
|
|
111
|
+
path2 = __toESM(require("path"), 1);
|
|
115
112
|
PROFILE_PATHS = [
|
|
116
113
|
"Google/Chrome",
|
|
117
114
|
"Arc/User Data",
|
|
@@ -124,10 +121,10 @@ var init_chrome_discover = __esm({
|
|
|
124
121
|
|
|
125
122
|
// package.json
|
|
126
123
|
var require_package = __commonJS({
|
|
127
|
-
"package.json"(
|
|
128
|
-
|
|
124
|
+
"package.json"(exports2, module2) {
|
|
125
|
+
module2.exports = {
|
|
129
126
|
name: "@ulpi/browse",
|
|
130
|
-
version: "1.0.
|
|
127
|
+
version: "1.0.3",
|
|
131
128
|
repository: {
|
|
132
129
|
type: "git",
|
|
133
130
|
url: "https://github.com/ulpi-io/browse"
|
|
@@ -141,7 +138,7 @@ var require_package = __commonJS({
|
|
|
141
138
|
"playwright-core": "^1.58.2"
|
|
142
139
|
},
|
|
143
140
|
bin: {
|
|
144
|
-
browse: "dist/browse.
|
|
141
|
+
browse: "dist/browse.cjs"
|
|
145
142
|
},
|
|
146
143
|
description: "Fast headless browser CLI \u2014 persistent Chromium daemon via Playwright.",
|
|
147
144
|
engines: {
|
|
@@ -168,7 +165,8 @@ var require_package = __commonJS({
|
|
|
168
165
|
access: "public"
|
|
169
166
|
},
|
|
170
167
|
scripts: {
|
|
171
|
-
build:
|
|
168
|
+
build: `esbuild src/cli.ts --bundle --format=cjs --platform=node --target=node18 --outfile=dist/browse.cjs --external:playwright --external:playwright-core --external:better-sqlite3 --external:electron --external:chromium-bidi --banner:js='#!/usr/bin/env node
|
|
169
|
+
const __import_meta_url = require("url").pathToFileURL(__filename).href;' --define:import.meta.url=__import_meta_url`,
|
|
172
170
|
"build:all": "bash scripts/build-all.sh",
|
|
173
171
|
dev: "tsx src/cli.ts",
|
|
174
172
|
server: "tsx src/server.ts",
|
|
@@ -199,9 +197,6 @@ var install_skill_exports = {};
|
|
|
199
197
|
__export(install_skill_exports, {
|
|
200
198
|
installSkill: () => installSkill
|
|
201
199
|
});
|
|
202
|
-
import * as fs3 from "fs";
|
|
203
|
-
import * as path3 from "path";
|
|
204
|
-
import { fileURLToPath } from "url";
|
|
205
200
|
function installSkill(targetDir) {
|
|
206
201
|
const dir = targetDir || process.cwd();
|
|
207
202
|
const hasGit = fs3.existsSync(path3.join(dir, ".git"));
|
|
@@ -213,7 +208,7 @@ function installSkill(targetDir) {
|
|
|
213
208
|
}
|
|
214
209
|
const skillDir = path3.join(dir, ".claude", "skills", "browse");
|
|
215
210
|
fs3.mkdirSync(skillDir, { recursive: true });
|
|
216
|
-
const skillSource = path3.resolve(path3.dirname(
|
|
211
|
+
const skillSource = path3.resolve(path3.dirname((0, import_url.fileURLToPath)(__import_meta_url)), "..", "skill", "SKILL.md");
|
|
217
212
|
const skillDest = path3.join(skillDir, "SKILL.md");
|
|
218
213
|
if (!fs3.existsSync(skillSource)) {
|
|
219
214
|
console.error(`SKILL.md not found at ${skillSource}`);
|
|
@@ -250,10 +245,13 @@ function installSkill(targetDir) {
|
|
|
250
245
|
}
|
|
251
246
|
console.log("\nDone. Claude Code will now use browse for web tasks automatically.");
|
|
252
247
|
}
|
|
253
|
-
var PERMISSIONS;
|
|
248
|
+
var fs3, path3, import_url, PERMISSIONS;
|
|
254
249
|
var init_install_skill = __esm({
|
|
255
250
|
"src/install-skill.ts"() {
|
|
256
251
|
"use strict";
|
|
252
|
+
fs3 = __toESM(require("fs"), 1);
|
|
253
|
+
path3 = __toESM(require("path"), 1);
|
|
254
|
+
import_url = require("url");
|
|
257
255
|
PERMISSIONS = [
|
|
258
256
|
"Bash(browse:*)",
|
|
259
257
|
"Bash(browse goto:*)",
|
|
@@ -319,35 +317,29 @@ var rebrowser_playwright_exports = {};
|
|
|
319
317
|
__export(rebrowser_playwright_exports, {
|
|
320
318
|
default: () => rebrowser_playwright_default
|
|
321
319
|
});
|
|
322
|
-
|
|
323
|
-
import playwright from "playwright-core";
|
|
324
|
-
var rebrowser_playwright_default;
|
|
320
|
+
var import_playwright_core, rebrowser_playwright_default;
|
|
325
321
|
var init_rebrowser_playwright = __esm({
|
|
326
322
|
"node_modules/rebrowser-playwright/index.mjs"() {
|
|
327
|
-
__reExport(rebrowser_playwright_exports,
|
|
328
|
-
|
|
323
|
+
__reExport(rebrowser_playwright_exports, require("playwright-core"));
|
|
324
|
+
import_playwright_core = __toESM(require("playwright-core"), 1);
|
|
325
|
+
rebrowser_playwright_default = import_playwright_core.default;
|
|
329
326
|
}
|
|
330
327
|
});
|
|
331
328
|
|
|
332
329
|
// src/runtime.ts
|
|
333
|
-
import { homedir as homedir2 } from "os";
|
|
334
|
-
import { existsSync as existsSync3 } from "fs";
|
|
335
|
-
import { execSync, spawn } from "child_process";
|
|
336
|
-
import { join as join4 } from "path";
|
|
337
|
-
import * as net from "net";
|
|
338
330
|
function findLightpanda() {
|
|
339
331
|
try {
|
|
340
|
-
const result = execSync("which lightpanda", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
332
|
+
const result = (0, import_child_process.execSync)("which lightpanda", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
341
333
|
if (result) return result;
|
|
342
334
|
} catch {
|
|
343
335
|
}
|
|
344
|
-
const home =
|
|
336
|
+
const home = (0, import_os.homedir)();
|
|
345
337
|
const candidates = [
|
|
346
|
-
|
|
347
|
-
|
|
338
|
+
(0, import_path.join)(home, ".lightpanda", "lightpanda"),
|
|
339
|
+
(0, import_path.join)(home, ".local", "bin", "lightpanda")
|
|
348
340
|
];
|
|
349
341
|
for (const candidate of candidates) {
|
|
350
|
-
if (
|
|
342
|
+
if ((0, import_fs.existsSync)(candidate)) return candidate;
|
|
351
343
|
}
|
|
352
344
|
return null;
|
|
353
345
|
}
|
|
@@ -361,10 +353,15 @@ async function getRuntime(name) {
|
|
|
361
353
|
}
|
|
362
354
|
return loader();
|
|
363
355
|
}
|
|
364
|
-
var registry, AVAILABLE_RUNTIMES;
|
|
356
|
+
var import_os, import_fs, import_child_process, import_path, net, registry, AVAILABLE_RUNTIMES;
|
|
365
357
|
var init_runtime = __esm({
|
|
366
358
|
"src/runtime.ts"() {
|
|
367
359
|
"use strict";
|
|
360
|
+
import_os = require("os");
|
|
361
|
+
import_fs = require("fs");
|
|
362
|
+
import_child_process = require("child_process");
|
|
363
|
+
import_path = require("path");
|
|
364
|
+
net = __toESM(require("net"), 1);
|
|
368
365
|
registry = {
|
|
369
366
|
playwright: async () => {
|
|
370
367
|
const pw = await import("playwright");
|
|
@@ -396,7 +393,7 @@ var init_runtime = __esm({
|
|
|
396
393
|
});
|
|
397
394
|
srv.on("error", reject);
|
|
398
395
|
});
|
|
399
|
-
const child = spawn(
|
|
396
|
+
const child = (0, import_child_process.spawn)(
|
|
400
397
|
binaryPath,
|
|
401
398
|
["serve", "--host", "127.0.0.1", "--port", String(port), "--timeout", "604800"],
|
|
402
399
|
{ stdio: ["ignore", "pipe", "pipe"] }
|
|
@@ -536,23 +533,20 @@ __export(browser_manager_exports, {
|
|
|
536
533
|
listProfiles: () => listProfiles,
|
|
537
534
|
resolveDevice: () => resolveDevice
|
|
538
535
|
});
|
|
539
|
-
import * as path4 from "path";
|
|
540
|
-
import * as fs4 from "fs";
|
|
541
|
-
import { chromium, devices as playwrightDevices } from "playwright";
|
|
542
536
|
function resolveDevice(name) {
|
|
543
537
|
const alias = DEVICE_ALIASES[name.toLowerCase()];
|
|
544
538
|
const aliasTarget = alias || name;
|
|
545
539
|
if (CUSTOM_DEVICES[aliasTarget]) {
|
|
546
540
|
return CUSTOM_DEVICES[aliasTarget];
|
|
547
541
|
}
|
|
548
|
-
if (
|
|
549
|
-
return
|
|
542
|
+
if (import_playwright.devices[aliasTarget]) {
|
|
543
|
+
return import_playwright.devices[aliasTarget];
|
|
550
544
|
}
|
|
551
545
|
const lower = name.toLowerCase();
|
|
552
546
|
for (const [key, desc] of Object.entries(CUSTOM_DEVICES)) {
|
|
553
547
|
if (key.toLowerCase() === lower) return desc;
|
|
554
548
|
}
|
|
555
|
-
for (const [key, desc] of Object.entries(
|
|
549
|
+
for (const [key, desc] of Object.entries(import_playwright.devices)) {
|
|
556
550
|
if (key.toLowerCase() === lower) {
|
|
557
551
|
return desc;
|
|
558
552
|
}
|
|
@@ -562,7 +556,7 @@ function resolveDevice(name) {
|
|
|
562
556
|
function listDevices() {
|
|
563
557
|
const all = /* @__PURE__ */ new Set([
|
|
564
558
|
...Object.keys(CUSTOM_DEVICES),
|
|
565
|
-
...Object.keys(
|
|
559
|
+
...Object.keys(import_playwright.devices)
|
|
566
560
|
]);
|
|
567
561
|
return [...all].sort();
|
|
568
562
|
}
|
|
@@ -603,10 +597,13 @@ function deleteProfile(localDir, name) {
|
|
|
603
597
|
if (!fs4.existsSync(dir)) throw new Error(`Profile "${name}" not found`);
|
|
604
598
|
fs4.rmSync(dir, { recursive: true, force: true });
|
|
605
599
|
}
|
|
606
|
-
var DEVICE_ALIASES, CUSTOM_DEVICES, BrowserManager;
|
|
600
|
+
var path4, fs4, import_playwright, DEVICE_ALIASES, CUSTOM_DEVICES, BrowserManager;
|
|
607
601
|
var init_browser_manager = __esm({
|
|
608
602
|
"src/browser-manager.ts"() {
|
|
609
603
|
"use strict";
|
|
604
|
+
path4 = __toESM(require("path"), 1);
|
|
605
|
+
fs4 = __toESM(require("fs"), 1);
|
|
606
|
+
import_playwright = require("playwright");
|
|
610
607
|
init_buffers();
|
|
611
608
|
init_sanitize();
|
|
612
609
|
DEVICE_ALIASES = {
|
|
@@ -737,7 +734,7 @@ var init_browser_manager = __esm({
|
|
|
737
734
|
* This instance owns the browser and will close it on close().
|
|
738
735
|
*/
|
|
739
736
|
async launch(onCrash) {
|
|
740
|
-
this.browser = await chromium.launch({ headless: true });
|
|
737
|
+
this.browser = await import_playwright.chromium.launch({ headless: true });
|
|
741
738
|
this.ownsBrowser = true;
|
|
742
739
|
this.browser.on("disconnected", () => {
|
|
743
740
|
if (onCrash) onCrash();
|
|
@@ -770,7 +767,7 @@ var init_browser_manager = __esm({
|
|
|
770
767
|
async launchPersistent(profileDir, onCrash) {
|
|
771
768
|
let context;
|
|
772
769
|
try {
|
|
773
|
-
context = await chromium.launchPersistentContext(profileDir, {
|
|
770
|
+
context = await import_playwright.chromium.launchPersistentContext(profileDir, {
|
|
774
771
|
headless: process.env.BROWSE_HEADED !== "1",
|
|
775
772
|
viewport: { width: 1920, height: 1080 },
|
|
776
773
|
...this.customUserAgent ? { userAgent: this.customUserAgent } : {}
|
|
@@ -780,7 +777,7 @@ var init_browser_manager = __esm({
|
|
|
780
777
|
const fs16 = await import("fs");
|
|
781
778
|
console.error(`[browse] Profile directory corrupted, recreating: ${profileDir}`);
|
|
782
779
|
fs16.rmSync(profileDir, { recursive: true, force: true });
|
|
783
|
-
context = await chromium.launchPersistentContext(profileDir, {
|
|
780
|
+
context = await import_playwright.chromium.launchPersistentContext(profileDir, {
|
|
784
781
|
headless: process.env.BROWSE_HEADED !== "1",
|
|
785
782
|
viewport: { width: 1920, height: 1080 }
|
|
786
783
|
});
|
|
@@ -1587,9 +1584,6 @@ var init_domain_filter = __esm({
|
|
|
1587
1584
|
});
|
|
1588
1585
|
|
|
1589
1586
|
// src/encryption.ts
|
|
1590
|
-
import * as crypto from "crypto";
|
|
1591
|
-
import * as fs5 from "fs";
|
|
1592
|
-
import * as path5 from "path";
|
|
1593
1587
|
function resolveEncryptionKey(localDir) {
|
|
1594
1588
|
const envKey = process.env.BROWSE_ENCRYPTION_KEY;
|
|
1595
1589
|
if (envKey) {
|
|
@@ -1630,9 +1624,13 @@ function decrypt(ciphertext, iv, authTag, key) {
|
|
|
1630
1624
|
]);
|
|
1631
1625
|
return decrypted.toString("utf-8");
|
|
1632
1626
|
}
|
|
1627
|
+
var crypto, fs5, path5;
|
|
1633
1628
|
var init_encryption = __esm({
|
|
1634
1629
|
"src/encryption.ts"() {
|
|
1635
1630
|
"use strict";
|
|
1631
|
+
crypto = __toESM(require("crypto"), 1);
|
|
1632
|
+
fs5 = __toESM(require("fs"), 1);
|
|
1633
|
+
path5 = __toESM(require("path"), 1);
|
|
1636
1634
|
}
|
|
1637
1635
|
});
|
|
1638
1636
|
|
|
@@ -1644,8 +1642,6 @@ __export(session_persist_exports, {
|
|
|
1644
1642
|
loadSessionState: () => loadSessionState,
|
|
1645
1643
|
saveSessionState: () => saveSessionState
|
|
1646
1644
|
});
|
|
1647
|
-
import * as fs6 from "fs";
|
|
1648
|
-
import * as path6 from "path";
|
|
1649
1645
|
async function saveSessionState(sessionDir, context, encryptionKey) {
|
|
1650
1646
|
try {
|
|
1651
1647
|
const state = await context.storageState();
|
|
@@ -1779,19 +1775,19 @@ function cleanOldStates(localDir, maxAgeDays) {
|
|
|
1779
1775
|
}
|
|
1780
1776
|
return { deleted };
|
|
1781
1777
|
}
|
|
1782
|
-
var STATE_FILENAME;
|
|
1778
|
+
var fs6, path6, STATE_FILENAME;
|
|
1783
1779
|
var init_session_persist = __esm({
|
|
1784
1780
|
"src/session-persist.ts"() {
|
|
1785
1781
|
"use strict";
|
|
1782
|
+
fs6 = __toESM(require("fs"), 1);
|
|
1783
|
+
path6 = __toESM(require("path"), 1);
|
|
1786
1784
|
init_encryption();
|
|
1787
1785
|
STATE_FILENAME = "state.json";
|
|
1788
1786
|
}
|
|
1789
1787
|
});
|
|
1790
1788
|
|
|
1791
1789
|
// src/session-manager.ts
|
|
1792
|
-
|
|
1793
|
-
import * as path7 from "path";
|
|
1794
|
-
var SessionManager;
|
|
1790
|
+
var fs7, path7, SessionManager;
|
|
1795
1791
|
var init_session_manager = __esm({
|
|
1796
1792
|
"src/session-manager.ts"() {
|
|
1797
1793
|
"use strict";
|
|
@@ -1801,6 +1797,8 @@ var init_session_manager = __esm({
|
|
|
1801
1797
|
init_sanitize();
|
|
1802
1798
|
init_session_persist();
|
|
1803
1799
|
init_encryption();
|
|
1800
|
+
fs7 = __toESM(require("fs"), 1);
|
|
1801
|
+
path7 = __toESM(require("path"), 1);
|
|
1804
1802
|
SessionManager = class {
|
|
1805
1803
|
sessions = /* @__PURE__ */ new Map();
|
|
1806
1804
|
browser;
|
|
@@ -1990,7 +1988,6 @@ var read_exports = {};
|
|
|
1990
1988
|
__export(read_exports, {
|
|
1991
1989
|
handleReadCommand: () => handleReadCommand
|
|
1992
1990
|
});
|
|
1993
|
-
import * as fs8 from "fs";
|
|
1994
1991
|
async function handleReadCommand(command, args, bm, buffers) {
|
|
1995
1992
|
const page = bm.getPage();
|
|
1996
1993
|
const evalCtx = await bm.getFrameContext() || page;
|
|
@@ -2324,11 +2321,13 @@ async function handleReadCommand(command, args, bm, buffers) {
|
|
|
2324
2321
|
throw new Error(`Unknown read command: ${command}`);
|
|
2325
2322
|
}
|
|
2326
2323
|
}
|
|
2324
|
+
var fs8;
|
|
2327
2325
|
var init_read = __esm({
|
|
2328
2326
|
"src/commands/read.ts"() {
|
|
2329
2327
|
"use strict";
|
|
2330
2328
|
init_browser_manager();
|
|
2331
2329
|
init_constants();
|
|
2330
|
+
fs8 = __toESM(require("fs"), 1);
|
|
2332
2331
|
}
|
|
2333
2332
|
});
|
|
2334
2333
|
|
|
@@ -2337,7 +2336,6 @@ var write_exports = {};
|
|
|
2337
2336
|
__export(write_exports, {
|
|
2338
2337
|
handleWriteCommand: () => handleWriteCommand
|
|
2339
2338
|
});
|
|
2340
|
-
import * as fs9 from "fs";
|
|
2341
2339
|
async function rebuildRoutes(context, bm, domainFilter) {
|
|
2342
2340
|
await context.unrouteAll();
|
|
2343
2341
|
for (const r of bm.getUserRoutes()) {
|
|
@@ -2951,11 +2949,13 @@ Note: Cookies and tab URLs preserved. localStorage/sessionStorage were reset (Pl
|
|
|
2951
2949
|
throw new Error(`Unknown write command: ${command}`);
|
|
2952
2950
|
}
|
|
2953
2951
|
}
|
|
2952
|
+
var fs9;
|
|
2954
2953
|
var init_write = __esm({
|
|
2955
2954
|
"src/commands/write.ts"() {
|
|
2956
2955
|
"use strict";
|
|
2957
2956
|
init_browser_manager();
|
|
2958
2957
|
init_constants();
|
|
2958
|
+
fs9 = __toESM(require("fs"), 1);
|
|
2959
2959
|
}
|
|
2960
2960
|
});
|
|
2961
2961
|
|
|
@@ -3919,8 +3919,6 @@ var policy_exports = {};
|
|
|
3919
3919
|
__export(policy_exports, {
|
|
3920
3920
|
PolicyChecker: () => PolicyChecker
|
|
3921
3921
|
});
|
|
3922
|
-
import * as fs10 from "fs";
|
|
3923
|
-
import * as path8 from "path";
|
|
3924
3922
|
function findFileUpward(filename) {
|
|
3925
3923
|
let dir = process.cwd();
|
|
3926
3924
|
for (let i = 0; i < 20; i++) {
|
|
@@ -3932,10 +3930,12 @@ function findFileUpward(filename) {
|
|
|
3932
3930
|
}
|
|
3933
3931
|
return null;
|
|
3934
3932
|
}
|
|
3935
|
-
var PolicyChecker;
|
|
3933
|
+
var fs10, path8, PolicyChecker;
|
|
3936
3934
|
var init_policy = __esm({
|
|
3937
3935
|
"src/policy.ts"() {
|
|
3938
3936
|
"use strict";
|
|
3937
|
+
fs10 = __toESM(require("fs"), 1);
|
|
3938
|
+
path8 = __toESM(require("path"), 1);
|
|
3939
3939
|
PolicyChecker = class {
|
|
3940
3940
|
filePath = null;
|
|
3941
3941
|
lastMtime = 0;
|
|
@@ -3988,7 +3988,6 @@ __export(png_compare_exports, {
|
|
|
3988
3988
|
encodePNG: () => encodePNG,
|
|
3989
3989
|
generateDiffImage: () => generateDiffImage
|
|
3990
3990
|
});
|
|
3991
|
-
import * as zlib from "zlib";
|
|
3992
3991
|
function decodePNG(buf) {
|
|
3993
3992
|
for (let i = 0; i < 8; i++) {
|
|
3994
3993
|
if (buf[i] !== PNG_MAGIC[i]) throw new Error("Not a valid PNG file");
|
|
@@ -4163,10 +4162,11 @@ function compareScreenshots(baselineBuf, currentBuf, thresholdPct = 0.1, colorTh
|
|
|
4163
4162
|
}
|
|
4164
4163
|
return result;
|
|
4165
4164
|
}
|
|
4166
|
-
var PNG_MAGIC;
|
|
4165
|
+
var zlib, PNG_MAGIC;
|
|
4167
4166
|
var init_png_compare = __esm({
|
|
4168
4167
|
"src/png-compare.ts"() {
|
|
4169
4168
|
"use strict";
|
|
4169
|
+
zlib = __toESM(require("zlib"), 1);
|
|
4170
4170
|
PNG_MAGIC = [137, 80, 78, 71, 13, 10, 26, 10];
|
|
4171
4171
|
}
|
|
4172
4172
|
});
|
|
@@ -4176,8 +4176,6 @@ var auth_vault_exports = {};
|
|
|
4176
4176
|
__export(auth_vault_exports, {
|
|
4177
4177
|
AuthVault: () => AuthVault
|
|
4178
4178
|
});
|
|
4179
|
-
import * as fs11 from "fs";
|
|
4180
|
-
import * as path9 from "path";
|
|
4181
4179
|
async function autoDetectSelector(page, field) {
|
|
4182
4180
|
if (field === "username") {
|
|
4183
4181
|
const candidates2 = [
|
|
@@ -4224,10 +4222,12 @@ async function autoDetectSelector(page, field) {
|
|
|
4224
4222
|
}
|
|
4225
4223
|
throw new Error("Could not auto-detect submit button.");
|
|
4226
4224
|
}
|
|
4227
|
-
var AuthVault;
|
|
4225
|
+
var fs11, path9, AuthVault;
|
|
4228
4226
|
var init_auth_vault = __esm({
|
|
4229
4227
|
"src/auth-vault.ts"() {
|
|
4230
4228
|
"use strict";
|
|
4229
|
+
fs11 = __toESM(require("fs"), 1);
|
|
4230
|
+
path9 = __toESM(require("path"), 1);
|
|
4231
4231
|
init_constants();
|
|
4232
4232
|
init_encryption();
|
|
4233
4233
|
init_sanitize();
|
|
@@ -4321,12 +4321,6 @@ __export(cookie_import_exports, {
|
|
|
4321
4321
|
importCookies: () => importCookies,
|
|
4322
4322
|
listDomains: () => listDomains
|
|
4323
4323
|
});
|
|
4324
|
-
import Database from "better-sqlite3";
|
|
4325
|
-
import { spawn as spawn2 } from "child_process";
|
|
4326
|
-
import * as crypto2 from "crypto";
|
|
4327
|
-
import * as fs12 from "fs";
|
|
4328
|
-
import * as path10 from "path";
|
|
4329
|
-
import * as os2 from "os";
|
|
4330
4324
|
function findInstalledBrowsers() {
|
|
4331
4325
|
const appSupport = path10.join(os2.homedir(), "Library", "Application Support");
|
|
4332
4326
|
return BROWSER_REGISTRY.filter((b) => {
|
|
@@ -4427,7 +4421,7 @@ function getCookieDbPath(browser2, profile) {
|
|
|
4427
4421
|
}
|
|
4428
4422
|
function openDb(dbPath, browserName) {
|
|
4429
4423
|
try {
|
|
4430
|
-
return new
|
|
4424
|
+
return new import_better_sqlite3.default(dbPath, { readonly: true });
|
|
4431
4425
|
} catch (err) {
|
|
4432
4426
|
if (err.message?.includes("SQLITE_BUSY") || err.message?.includes("database is locked")) {
|
|
4433
4427
|
return openDbFromCopy(dbPath, browserName);
|
|
@@ -4449,7 +4443,7 @@ function openDbFromCopy(dbPath, browserName) {
|
|
|
4449
4443
|
const shmPath = dbPath + "-shm";
|
|
4450
4444
|
if (fs12.existsSync(walPath)) fs12.copyFileSync(walPath, tmpPath + "-wal");
|
|
4451
4445
|
if (fs12.existsSync(shmPath)) fs12.copyFileSync(shmPath, tmpPath + "-shm");
|
|
4452
|
-
const db = new
|
|
4446
|
+
const db = new import_better_sqlite3.default(tmpPath, { readonly: true });
|
|
4453
4447
|
const origClose = db.close.bind(db);
|
|
4454
4448
|
db.close = (() => {
|
|
4455
4449
|
origClose();
|
|
@@ -4488,7 +4482,7 @@ async function getDerivedKey(browser2) {
|
|
|
4488
4482
|
return derived;
|
|
4489
4483
|
}
|
|
4490
4484
|
async function getKeychainPassword(service) {
|
|
4491
|
-
const proc =
|
|
4485
|
+
const proc = (0, import_child_process2.spawn)("security", ["find-generic-password", "-s", service, "-w"], {
|
|
4492
4486
|
stdio: ["ignore", "pipe", "pipe"]
|
|
4493
4487
|
});
|
|
4494
4488
|
let stdout = "";
|
|
@@ -4595,10 +4589,16 @@ function mapSameSite(value) {
|
|
|
4595
4589
|
return "Lax";
|
|
4596
4590
|
}
|
|
4597
4591
|
}
|
|
4598
|
-
var CookieImportError, BROWSER_REGISTRY, keyCache, CHROMIUM_EPOCH_OFFSET;
|
|
4592
|
+
var import_better_sqlite3, import_child_process2, crypto2, fs12, path10, os2, CookieImportError, BROWSER_REGISTRY, keyCache, CHROMIUM_EPOCH_OFFSET;
|
|
4599
4593
|
var init_cookie_import = __esm({
|
|
4600
4594
|
"src/cookie-import.ts"() {
|
|
4601
4595
|
"use strict";
|
|
4596
|
+
import_better_sqlite3 = __toESM(require("better-sqlite3"), 1);
|
|
4597
|
+
import_child_process2 = require("child_process");
|
|
4598
|
+
crypto2 = __toESM(require("crypto"), 1);
|
|
4599
|
+
fs12 = __toESM(require("fs"), 1);
|
|
4600
|
+
path10 = __toESM(require("path"), 1);
|
|
4601
|
+
os2 = __toESM(require("os"), 1);
|
|
4602
4602
|
CookieImportError = class extends Error {
|
|
4603
4603
|
constructor(message, code, action) {
|
|
4604
4604
|
super(message);
|
|
@@ -4767,7 +4767,6 @@ var init_record_export = __esm({
|
|
|
4767
4767
|
});
|
|
4768
4768
|
|
|
4769
4769
|
// src/commands/meta.ts
|
|
4770
|
-
import * as fs13 from "fs";
|
|
4771
4770
|
async function handleMetaCommand(command, args, bm, shutdown2, sessionManager2, currentSession) {
|
|
4772
4771
|
switch (command) {
|
|
4773
4772
|
// ─── Tabs ──────────────────────────────────────────
|
|
@@ -5666,7 +5665,7 @@ Manual: npm install -g @ulpi/browse`;
|
|
|
5666
5665
|
throw new Error(`Unknown meta command: ${command}`);
|
|
5667
5666
|
}
|
|
5668
5667
|
}
|
|
5669
|
-
var LOCAL_DIR;
|
|
5668
|
+
var fs13, LOCAL_DIR;
|
|
5670
5669
|
var init_meta = __esm({
|
|
5671
5670
|
"src/commands/meta.ts"() {
|
|
5672
5671
|
"use strict";
|
|
@@ -5674,18 +5673,13 @@ var init_meta = __esm({
|
|
|
5674
5673
|
init_constants();
|
|
5675
5674
|
init_sanitize();
|
|
5676
5675
|
init_lib();
|
|
5676
|
+
fs13 = __toESM(require("fs"), 1);
|
|
5677
5677
|
LOCAL_DIR = process.env.BROWSE_LOCAL_DIR || "/tmp";
|
|
5678
5678
|
}
|
|
5679
5679
|
});
|
|
5680
5680
|
|
|
5681
5681
|
// src/server.ts
|
|
5682
5682
|
var server_exports = {};
|
|
5683
|
-
import * as fs14 from "fs";
|
|
5684
|
-
import * as path11 from "path";
|
|
5685
|
-
import * as crypto3 from "crypto";
|
|
5686
|
-
import * as http from "http";
|
|
5687
|
-
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
5688
|
-
import * as net2 from "net";
|
|
5689
5683
|
function nodeServe(opts) {
|
|
5690
5684
|
const server = http.createServer(async (nodeReq, nodeRes) => {
|
|
5691
5685
|
try {
|
|
@@ -6097,7 +6091,7 @@ async function start() {
|
|
|
6097
6091
|
port,
|
|
6098
6092
|
token: AUTH_TOKEN,
|
|
6099
6093
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6100
|
-
serverPath: path11.resolve(path11.dirname(
|
|
6094
|
+
serverPath: path11.resolve(path11.dirname((0, import_url2.fileURLToPath)(__import_meta_url)), "server.ts")
|
|
6101
6095
|
};
|
|
6102
6096
|
if (profileName) {
|
|
6103
6097
|
state.profile = profileName;
|
|
@@ -6110,7 +6104,7 @@ async function start() {
|
|
|
6110
6104
|
console.log(`[browse] State file: ${STATE_FILE}`);
|
|
6111
6105
|
console.log(`[browse] Idle timeout: ${IDLE_TIMEOUT_MS / 1e3}s`);
|
|
6112
6106
|
}
|
|
6113
|
-
var AUTH_TOKEN, DEBUG_PORT, BROWSE_PORT, BROWSE_INSTANCE, INSTANCE_SUFFIX, LOCAL_DIR2, STATE_FILE, IDLE_TIMEOUT_MS, sessionManager, browser, profileSession, activeRuntime, isShuttingDown, isRemoteBrowser, policyChecker, READ_COMMANDS, WRITE_COMMANDS, META_COMMANDS, RECORDING_SKIP, PAGE_CONTENT_COMMANDS, BOUNDARY_NONCE, flushInterval, sessionCleanupInterval;
|
|
6107
|
+
var fs14, path11, crypto3, http, import_url2, net2, AUTH_TOKEN, DEBUG_PORT, BROWSE_PORT, BROWSE_INSTANCE, INSTANCE_SUFFIX, LOCAL_DIR2, STATE_FILE, IDLE_TIMEOUT_MS, sessionManager, browser, profileSession, activeRuntime, isShuttingDown, isRemoteBrowser, policyChecker, READ_COMMANDS, WRITE_COMMANDS, META_COMMANDS, RECORDING_SKIP, PAGE_CONTENT_COMMANDS, BOUNDARY_NONCE, flushInterval, sessionCleanupInterval;
|
|
6114
6108
|
var init_server = __esm({
|
|
6115
6109
|
"src/server.ts"() {
|
|
6116
6110
|
"use strict";
|
|
@@ -6121,6 +6115,12 @@ var init_server = __esm({
|
|
|
6121
6115
|
init_meta();
|
|
6122
6116
|
init_policy();
|
|
6123
6117
|
init_constants();
|
|
6118
|
+
fs14 = __toESM(require("fs"), 1);
|
|
6119
|
+
path11 = __toESM(require("path"), 1);
|
|
6120
|
+
crypto3 = __toESM(require("crypto"), 1);
|
|
6121
|
+
http = __toESM(require("http"), 1);
|
|
6122
|
+
import_url2 = require("url");
|
|
6123
|
+
net2 = __toESM(require("net"), 1);
|
|
6124
6124
|
AUTH_TOKEN = crypto3.randomUUID();
|
|
6125
6125
|
DEBUG_PORT = parseInt(process.env.BROWSE_DEBUG_PORT || "0", 10);
|
|
6126
6126
|
BROWSE_PORT = parseInt(process.env.BROWSE_PORT || "0", 10);
|
|
@@ -6291,15 +6291,22 @@ var init_server = __esm({
|
|
|
6291
6291
|
});
|
|
6292
6292
|
|
|
6293
6293
|
// src/cli.ts
|
|
6294
|
+
var cli_exports = {};
|
|
6295
|
+
__export(cli_exports, {
|
|
6296
|
+
SAFE_TO_RETRY: () => SAFE_TO_RETRY,
|
|
6297
|
+
main: () => main,
|
|
6298
|
+
resolveServerScript: () => resolveServerScript
|
|
6299
|
+
});
|
|
6300
|
+
module.exports = __toCommonJS(cli_exports);
|
|
6301
|
+
var fs15 = __toESM(require("fs"), 1);
|
|
6302
|
+
var path12 = __toESM(require("path"), 1);
|
|
6303
|
+
var import_child_process3 = require("child_process");
|
|
6304
|
+
var import_url3 = require("url");
|
|
6294
6305
|
init_constants();
|
|
6295
|
-
import * as fs15 from "fs";
|
|
6296
|
-
import * as path12 from "path";
|
|
6297
|
-
import { spawn as spawn3 } from "child_process";
|
|
6298
|
-
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
6299
6306
|
|
|
6300
6307
|
// src/config.ts
|
|
6301
|
-
|
|
6302
|
-
|
|
6308
|
+
var fs = __toESM(require("fs"), 1);
|
|
6309
|
+
var path = __toESM(require("path"), 1);
|
|
6303
6310
|
function loadConfig() {
|
|
6304
6311
|
let dir = process.cwd();
|
|
6305
6312
|
for (let i = 0; i < 20; i++) {
|
|
@@ -6376,7 +6383,7 @@ var STATE_FILE2 = process.env.BROWSE_STATE_FILE || path12.join(LOCAL_DIR3, `brow
|
|
|
6376
6383
|
var MAX_START_WAIT = 8e3;
|
|
6377
6384
|
var LOCK_FILE = STATE_FILE2 + ".lock";
|
|
6378
6385
|
var LOCK_STALE_MS = DEFAULTS.LOCK_STALE_THRESHOLD_MS;
|
|
6379
|
-
var __filename_cli =
|
|
6386
|
+
var __filename_cli = (0, import_url3.fileURLToPath)(__import_meta_url);
|
|
6380
6387
|
var __dirname_cli = path12.dirname(__filename_cli);
|
|
6381
6388
|
function resolveServerScript(env = process.env, metaDir = __dirname_cli) {
|
|
6382
6389
|
if (env.BROWSE_SERVER_SCRIPT) {
|
|
@@ -6388,7 +6395,7 @@ function resolveServerScript(env = process.env, metaDir = __dirname_cli) {
|
|
|
6388
6395
|
return direct;
|
|
6389
6396
|
}
|
|
6390
6397
|
}
|
|
6391
|
-
const selfPath =
|
|
6398
|
+
const selfPath = (0, import_url3.fileURLToPath)(__import_meta_url);
|
|
6392
6399
|
if (fs15.existsSync(selfPath)) {
|
|
6393
6400
|
return "__self__";
|
|
6394
6401
|
}
|
|
@@ -6462,7 +6469,7 @@ async function listInstances() {
|
|
|
6462
6469
|
}
|
|
6463
6470
|
function isBrowseProcess(pid) {
|
|
6464
6471
|
try {
|
|
6465
|
-
const { execSync: execSync2 } =
|
|
6472
|
+
const { execSync: execSync2 } = require("child_process");
|
|
6466
6473
|
const cmd = execSync2(`ps -p ${pid} -o command=`, { encoding: "utf-8" }).trim();
|
|
6467
6474
|
return cmd.includes("browse") || cmd.includes("__BROWSE_SERVER_MODE");
|
|
6468
6475
|
} catch {
|
|
@@ -6524,10 +6531,10 @@ async function startServer() {
|
|
|
6524
6531
|
}
|
|
6525
6532
|
} catch {
|
|
6526
6533
|
}
|
|
6527
|
-
const selfPath =
|
|
6534
|
+
const selfPath = (0, import_url3.fileURLToPath)(__import_meta_url);
|
|
6528
6535
|
const spawnCmd = SERVER_SCRIPT === "__self__" ? [process.execPath, selfPath] : [process.execPath, "--import", "tsx", SERVER_SCRIPT];
|
|
6529
6536
|
const spawnEnv = { ...process.env, __BROWSE_SERVER_MODE: "1", BROWSE_LOCAL_DIR: LOCAL_DIR3, BROWSE_INSTANCE: BROWSE_INSTANCE2, ...cliFlags.headed ? { BROWSE_HEADED: "1" } : {}, ...cliFlags.cdpUrl ? { BROWSE_CDP_URL: cliFlags.cdpUrl } : {}, ...cliFlags.profile ? { BROWSE_PROFILE: cliFlags.profile } : {} };
|
|
6530
|
-
const proc =
|
|
6537
|
+
const proc = (0, import_child_process3.spawn)(spawnCmd[0], spawnCmd.slice(1), {
|
|
6531
6538
|
stdio: ["ignore", "ignore", "pipe"],
|
|
6532
6539
|
env: spawnEnv,
|
|
6533
6540
|
detached: true
|
|
@@ -7020,8 +7027,9 @@ if (process.env.__BROWSE_SERVER_MODE === "1") {
|
|
|
7020
7027
|
process.exit(1);
|
|
7021
7028
|
});
|
|
7022
7029
|
}
|
|
7023
|
-
export
|
|
7030
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
7031
|
+
0 && (module.exports = {
|
|
7024
7032
|
SAFE_TO_RETRY,
|
|
7025
7033
|
main,
|
|
7026
7034
|
resolveServerScript
|
|
7027
|
-
};
|
|
7035
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ulpi/browse",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/ulpi-io/browse"
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"playwright-core": "^1.58.2"
|
|
15
15
|
},
|
|
16
16
|
"bin": {
|
|
17
|
-
"browse": "dist/browse.
|
|
17
|
+
"browse": "dist/browse.cjs"
|
|
18
18
|
},
|
|
19
19
|
"description": "Fast headless browser CLI — persistent Chromium daemon via Playwright.",
|
|
20
20
|
"engines": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"access": "public"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
|
-
"build": "esbuild src/cli.ts --bundle --format=
|
|
44
|
+
"build": "esbuild src/cli.ts --bundle --format=cjs --platform=node --target=node18 --outfile=dist/browse.cjs --external:playwright --external:playwright-core --external:better-sqlite3 --external:electron --external:chromium-bidi --banner:js='#!/usr/bin/env node\nconst __import_meta_url = require(\"url\").pathToFileURL(__filename).href;' --define:import.meta.url=__import_meta_url",
|
|
45
45
|
"build:all": "bash scripts/build-all.sh",
|
|
46
46
|
"dev": "tsx src/cli.ts",
|
|
47
47
|
"server": "tsx src/server.ts",
|