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