@hasna/browser 0.3.7 → 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/dist/cli/index.js +557 -395
- package/dist/engines/selector.d.ts.map +1 -1
- package/dist/engines/tui.d.ts +49 -0
- package/dist/engines/tui.d.ts.map +1 -0
- package/dist/engines/tui.test.d.ts +2 -0
- package/dist/engines/tui.test.d.ts.map +1 -0
- package/dist/index.js +8362 -7856
- package/dist/lib/actions.d.ts +1 -0
- package/dist/lib/actions.d.ts.map +1 -1
- package/dist/lib/coordination.d.ts.map +1 -1
- package/dist/lib/login-scripts.d.ts +89 -0
- package/dist/lib/login-scripts.d.ts.map +1 -0
- package/dist/lib/network.d.ts.map +1 -1
- package/dist/lib/page-memory.d.ts.map +1 -1
- package/dist/lib/session.d.ts.map +1 -1
- package/dist/lib/task-queue.d.ts.map +1 -1
- package/dist/mcp/index.js +553 -391
- package/dist/server/index.js +1157 -327
- package/dist/types/index.d.ts +3 -2
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/mcp/index.js
CHANGED
|
@@ -6,60 +6,39 @@ var __defProp = Object.defineProperty;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
function __accessProp(key) {
|
|
10
|
-
return this[key];
|
|
11
|
-
}
|
|
12
|
-
var __toESMCache_node;
|
|
13
|
-
var __toESMCache_esm;
|
|
14
9
|
var __toESM = (mod, isNodeMode, target) => {
|
|
15
|
-
var canCache = mod != null && typeof mod === "object";
|
|
16
|
-
if (canCache) {
|
|
17
|
-
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
18
|
-
var cached = cache.get(mod);
|
|
19
|
-
if (cached)
|
|
20
|
-
return cached;
|
|
21
|
-
}
|
|
22
10
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
23
11
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
24
12
|
for (let key of __getOwnPropNames(mod))
|
|
25
13
|
if (!__hasOwnProp.call(to, key))
|
|
26
14
|
__defProp(to, key, {
|
|
27
|
-
get:
|
|
15
|
+
get: () => mod[key],
|
|
28
16
|
enumerable: true
|
|
29
17
|
});
|
|
30
|
-
if (canCache)
|
|
31
|
-
cache.set(mod, to);
|
|
32
18
|
return to;
|
|
33
19
|
};
|
|
20
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
34
21
|
var __toCommonJS = (from) => {
|
|
35
|
-
var entry =
|
|
22
|
+
var entry = __moduleCache.get(from), desc;
|
|
36
23
|
if (entry)
|
|
37
24
|
return entry;
|
|
38
25
|
entry = __defProp({}, "__esModule", { value: true });
|
|
39
|
-
if (from && typeof from === "object" || typeof from === "function")
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
45
|
-
});
|
|
46
|
-
}
|
|
26
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
27
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
28
|
+
get: () => from[key],
|
|
29
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
30
|
+
}));
|
|
47
31
|
__moduleCache.set(from, entry);
|
|
48
32
|
return entry;
|
|
49
33
|
};
|
|
50
|
-
var __moduleCache;
|
|
51
34
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
52
|
-
var __returnValue = (v) => v;
|
|
53
|
-
function __exportSetter(name, newValue) {
|
|
54
|
-
this[name] = __returnValue.bind(null, newValue);
|
|
55
|
-
}
|
|
56
35
|
var __export = (target, all) => {
|
|
57
36
|
for (var name in all)
|
|
58
37
|
__defProp(target, name, {
|
|
59
38
|
get: all[name],
|
|
60
39
|
enumerable: true,
|
|
61
40
|
configurable: true,
|
|
62
|
-
set:
|
|
41
|
+
set: (newValue) => all[name] = () => newValue
|
|
63
42
|
});
|
|
64
43
|
};
|
|
65
44
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
@@ -143,11 +122,11 @@ import { homedir as homedir4 } from "os";
|
|
|
143
122
|
import { join as join4 } from "path";
|
|
144
123
|
import { join as join6, dirname } from "path";
|
|
145
124
|
import { homedir as homedir5, platform } from "os";
|
|
146
|
-
function
|
|
125
|
+
function __accessProp(key) {
|
|
147
126
|
return this[key];
|
|
148
127
|
}
|
|
149
|
-
function
|
|
150
|
-
this[name] =
|
|
128
|
+
function __exportSetter(name, newValue) {
|
|
129
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
151
130
|
}
|
|
152
131
|
function translateSql(sql, dialect) {
|
|
153
132
|
if (dialect === "sqlite")
|
|
@@ -1177,10 +1156,10 @@ class SyncProgressTracker {
|
|
|
1177
1156
|
}
|
|
1178
1157
|
}
|
|
1179
1158
|
}
|
|
1180
|
-
var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2,
|
|
1159
|
+
var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2, __toESMCache_node, __toESMCache_esm, __toESM2 = (mod, isNodeMode, target) => {
|
|
1181
1160
|
var canCache = mod != null && typeof mod === "object";
|
|
1182
1161
|
if (canCache) {
|
|
1183
|
-
var cache = isNodeMode ?
|
|
1162
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
1184
1163
|
var cached = cache.get(mod);
|
|
1185
1164
|
if (cached)
|
|
1186
1165
|
return cached;
|
|
@@ -1190,19 +1169,19 @@ var __create2, __getProtoOf2, __defProp2, __getOwnPropNames2, __hasOwnProp2, __t
|
|
|
1190
1169
|
for (let key of __getOwnPropNames2(mod))
|
|
1191
1170
|
if (!__hasOwnProp2.call(to, key))
|
|
1192
1171
|
__defProp2(to, key, {
|
|
1193
|
-
get:
|
|
1172
|
+
get: __accessProp.bind(mod, key),
|
|
1194
1173
|
enumerable: true
|
|
1195
1174
|
});
|
|
1196
1175
|
if (canCache)
|
|
1197
1176
|
cache.set(mod, to);
|
|
1198
1177
|
return to;
|
|
1199
|
-
}, __commonJS2 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports),
|
|
1178
|
+
}, __commonJS2 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports), __returnValue = (v) => v, __export2 = (target, all) => {
|
|
1200
1179
|
for (var name in all)
|
|
1201
1180
|
__defProp2(target, name, {
|
|
1202
1181
|
get: all[name],
|
|
1203
1182
|
enumerable: true,
|
|
1204
1183
|
configurable: true,
|
|
1205
|
-
set:
|
|
1184
|
+
set: __exportSetter.bind(all, name)
|
|
1206
1185
|
});
|
|
1207
1186
|
}, __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), __require2, require_postgres_array, require_arrayParser, require_postgres_date, require_mutable, require_postgres_interval, require_postgres_bytea, require_textParsers, require_pg_int8, require_binaryParsers, require_builtins, require_pg_types, require_defaults, require_utils, require_utils_legacy, require_utils_webcrypto, require_utils2, require_cert_signatures, require_sasl, require_type_overrides, require_pg_connection_string, require_connection_parameters, require_result, require_query, require_messages, require_buffer_writer, require_serializer, require_buffer_reader, require_parser, require_dist, require_empty, require_stream, require_connection, require_split2, require_helper, require_lib, require_client, require_pg_pool, require_query2, require_client2, require_lib2, import_lib, Client, Pool, Connection, types2, Query, DatabaseError, escapeIdentifier, escapeLiteral, Result, TypeOverrides, defaults, esm_default, init_esm, init_adapter, util3, objectUtil2, ZodParsedType2, getParsedType2 = (data) => {
|
|
1208
1187
|
const t = typeof data;
|
|
@@ -10619,6 +10598,89 @@ var init_bun_webview = __esm(() => {
|
|
|
10619
10598
|
};
|
|
10620
10599
|
});
|
|
10621
10600
|
|
|
10601
|
+
// src/engines/tui.ts
|
|
10602
|
+
import { execSync as execSync2, spawn as spawn2 } from "child_process";
|
|
10603
|
+
function isTuiAvailable() {
|
|
10604
|
+
try {
|
|
10605
|
+
execSync2("which ttyd", { stdio: "ignore" });
|
|
10606
|
+
return true;
|
|
10607
|
+
} catch {
|
|
10608
|
+
return false;
|
|
10609
|
+
}
|
|
10610
|
+
}
|
|
10611
|
+
async function findAvailablePort(startPort) {
|
|
10612
|
+
let port = startPort;
|
|
10613
|
+
for (let i = 0;i < 100; i++) {
|
|
10614
|
+
try {
|
|
10615
|
+
const resp = await fetch(`http://localhost:${port}`);
|
|
10616
|
+
port++;
|
|
10617
|
+
} catch {
|
|
10618
|
+
return port;
|
|
10619
|
+
}
|
|
10620
|
+
}
|
|
10621
|
+
throw new BrowserError("No available port found for ttyd", "TUI_PORT_EXHAUSTED");
|
|
10622
|
+
}
|
|
10623
|
+
async function waitForTtyd(port, timeoutMs = 1e4) {
|
|
10624
|
+
const start = Date.now();
|
|
10625
|
+
while (Date.now() - start < timeoutMs) {
|
|
10626
|
+
try {
|
|
10627
|
+
const resp = await fetch(`http://localhost:${port}`);
|
|
10628
|
+
if (resp.ok || resp.status === 200)
|
|
10629
|
+
return;
|
|
10630
|
+
} catch {}
|
|
10631
|
+
await new Promise((r) => setTimeout(r, 150));
|
|
10632
|
+
}
|
|
10633
|
+
throw new BrowserError(`ttyd did not start within ${timeoutMs}ms`, "TUI_TIMEOUT");
|
|
10634
|
+
}
|
|
10635
|
+
async function launchTui(command, options = {}) {
|
|
10636
|
+
if (!isTuiAvailable()) {
|
|
10637
|
+
throw new BrowserError("ttyd not found \u2014 install with: brew install ttyd", "TUI_NOT_AVAILABLE");
|
|
10638
|
+
}
|
|
10639
|
+
const port = await findAvailablePort(nextPort);
|
|
10640
|
+
nextPort = port + 1;
|
|
10641
|
+
const ttydProcess = spawn2("ttyd", ["--writable", "--port", String(port), "/bin/sh", "-c", command], {
|
|
10642
|
+
stdio: "ignore",
|
|
10643
|
+
detached: false
|
|
10644
|
+
});
|
|
10645
|
+
ttydProcess.on("error", (err) => {
|
|
10646
|
+
console.error(`[tui] ttyd process error: ${err.message}`);
|
|
10647
|
+
});
|
|
10648
|
+
try {
|
|
10649
|
+
await waitForTtyd(port);
|
|
10650
|
+
const viewport = options.viewport ?? { width: 1280, height: 720 };
|
|
10651
|
+
const browser = await launchPlaywright({
|
|
10652
|
+
headless: options.headless ?? true,
|
|
10653
|
+
viewport
|
|
10654
|
+
});
|
|
10655
|
+
const page = await getPage(browser, { viewport });
|
|
10656
|
+
await page.goto(`http://localhost:${port}`, {
|
|
10657
|
+
waitUntil: "domcontentloaded"
|
|
10658
|
+
});
|
|
10659
|
+
await page.waitForSelector(".xterm-screen", { timeout: 1e4 });
|
|
10660
|
+
return { ttydProcess, port, browser, page };
|
|
10661
|
+
} catch (err) {
|
|
10662
|
+
ttydProcess.kill();
|
|
10663
|
+
throw err;
|
|
10664
|
+
}
|
|
10665
|
+
}
|
|
10666
|
+
async function closeTui(session) {
|
|
10667
|
+
try {
|
|
10668
|
+
await session.page.close();
|
|
10669
|
+
} catch {}
|
|
10670
|
+
try {
|
|
10671
|
+
await session.browser.close();
|
|
10672
|
+
} catch {}
|
|
10673
|
+
try {
|
|
10674
|
+
session.ttydProcess.kill("SIGTERM");
|
|
10675
|
+
} catch {}
|
|
10676
|
+
}
|
|
10677
|
+
var DEFAULT_TTYD_PORT_START = 7780, nextPort;
|
|
10678
|
+
var init_tui = __esm(() => {
|
|
10679
|
+
init_types();
|
|
10680
|
+
init_playwright();
|
|
10681
|
+
nextPort = DEFAULT_TTYD_PORT_START;
|
|
10682
|
+
});
|
|
10683
|
+
|
|
10622
10684
|
// src/engines/selector.ts
|
|
10623
10685
|
function selectEngine(useCase, explicit) {
|
|
10624
10686
|
if (explicit && explicit !== "auto")
|
|
@@ -10642,6 +10704,7 @@ var init_selector = __esm(() => {
|
|
|
10642
10704
|
init_types();
|
|
10643
10705
|
init_lightpanda();
|
|
10644
10706
|
init_bun_webview();
|
|
10707
|
+
init_tui();
|
|
10645
10708
|
ENGINE_MAP = {
|
|
10646
10709
|
["scrape" /* SCRAPE */]: "bun",
|
|
10647
10710
|
["extract_links" /* EXTRACT_LINKS */]: "bun",
|
|
@@ -10652,6 +10715,7 @@ var init_selector = __esm(() => {
|
|
|
10652
10715
|
["auth_flow" /* AUTH_FLOW */]: "playwright",
|
|
10653
10716
|
["multi_tab" /* MULTI_TAB */]: "playwright",
|
|
10654
10717
|
["record_replay" /* RECORD_REPLAY */]: "playwright",
|
|
10718
|
+
["terminal_test" /* TERMINAL_TEST */]: "tui",
|
|
10655
10719
|
["network_monitor" /* NETWORK_MONITOR */]: "cdp",
|
|
10656
10720
|
["har_capture" /* HAR_CAPTURE */]: "cdp",
|
|
10657
10721
|
["perf_profile" /* PERF_PROFILE */]: "cdp",
|
|
@@ -10773,7 +10837,8 @@ function startHAR(page) {
|
|
|
10773
10837
|
},
|
|
10774
10838
|
timings: { send: 0, wait: duration, receive: 0 }
|
|
10775
10839
|
};
|
|
10776
|
-
entries.
|
|
10840
|
+
if (entries.length < HAR_MAX_ENTRIES)
|
|
10841
|
+
entries.push(entry);
|
|
10777
10842
|
};
|
|
10778
10843
|
const onRequestFailed = (req) => {
|
|
10779
10844
|
requestStart.delete(req.url() + req.method());
|
|
@@ -10798,6 +10863,7 @@ function startHAR(page) {
|
|
|
10798
10863
|
}
|
|
10799
10864
|
};
|
|
10800
10865
|
}
|
|
10866
|
+
var HAR_MAX_ENTRIES = 5000;
|
|
10801
10867
|
var init_network = __esm(() => {
|
|
10802
10868
|
init_network_log();
|
|
10803
10869
|
});
|
|
@@ -11200,337 +11266,6 @@ var init_storage_state = __esm(() => {
|
|
|
11200
11266
|
STATES_DIR = join8(getDataDir2(), "states");
|
|
11201
11267
|
});
|
|
11202
11268
|
|
|
11203
|
-
// src/lib/session.ts
|
|
11204
|
-
var exports_session = {};
|
|
11205
|
-
__export(exports_session, {
|
|
11206
|
-
setSessionPage: () => setSessionPage,
|
|
11207
|
-
renameSession: () => renameSession2,
|
|
11208
|
-
listSessions: () => listSessions2,
|
|
11209
|
-
isBunSession: () => isBunSession,
|
|
11210
|
-
isAutoGallery: () => isAutoGallery,
|
|
11211
|
-
hasActiveHandle: () => hasActiveHandle,
|
|
11212
|
-
getTokenBudget: () => getTokenBudget,
|
|
11213
|
-
getSessionPage: () => getSessionPage,
|
|
11214
|
-
getSessionEngine: () => getSessionEngine,
|
|
11215
|
-
getSessionByName: () => getSessionByName2,
|
|
11216
|
-
getSessionBunView: () => getSessionBunView,
|
|
11217
|
-
getSessionBrowser: () => getSessionBrowser,
|
|
11218
|
-
getSession: () => getSession2,
|
|
11219
|
-
getDefaultSession: () => getDefaultSession,
|
|
11220
|
-
getActiveSessions: () => getActiveSessions,
|
|
11221
|
-
getActiveSessionForAgent: () => getActiveSessionForAgent2,
|
|
11222
|
-
createSession: () => createSession2,
|
|
11223
|
-
countActiveSessions: () => countActiveSessions2,
|
|
11224
|
-
closeSession: () => closeSession2,
|
|
11225
|
-
closeAllSessions: () => closeAllSessions,
|
|
11226
|
-
browserPool: () => pool
|
|
11227
|
-
});
|
|
11228
|
-
function createBunProxy(view) {
|
|
11229
|
-
return view;
|
|
11230
|
-
}
|
|
11231
|
-
async function createSession2(opts = {}) {
|
|
11232
|
-
if (opts.cdpUrl) {
|
|
11233
|
-
const { connectToExistingBrowser: connectToExistingBrowser2 } = await Promise.resolve().then(() => (init_cdp(), exports_cdp));
|
|
11234
|
-
const cdpBrowser = await connectToExistingBrowser2(opts.cdpUrl);
|
|
11235
|
-
const contexts = cdpBrowser.contexts();
|
|
11236
|
-
const context = contexts.length > 0 ? contexts[0] : await cdpBrowser.newContext();
|
|
11237
|
-
const pages = context.pages();
|
|
11238
|
-
const page2 = pages.length > 0 ? pages[0] : await context.newPage();
|
|
11239
|
-
const session2 = createSession({
|
|
11240
|
-
engine: "cdp",
|
|
11241
|
-
projectId: opts.projectId,
|
|
11242
|
-
agentId: opts.agentId,
|
|
11243
|
-
startUrl: page2.url(),
|
|
11244
|
-
name: opts.name ?? "attached"
|
|
11245
|
-
});
|
|
11246
|
-
const cleanups2 = [];
|
|
11247
|
-
if (opts.captureNetwork !== false) {
|
|
11248
|
-
try {
|
|
11249
|
-
cleanups2.push(enableNetworkLogging(page2, session2.id));
|
|
11250
|
-
} catch {}
|
|
11251
|
-
}
|
|
11252
|
-
if (opts.captureConsole !== false) {
|
|
11253
|
-
try {
|
|
11254
|
-
cleanups2.push(enableConsoleCapture(page2, session2.id));
|
|
11255
|
-
} catch {}
|
|
11256
|
-
}
|
|
11257
|
-
try {
|
|
11258
|
-
cleanups2.push(setupDialogHandler(page2, session2.id));
|
|
11259
|
-
} catch {}
|
|
11260
|
-
handles.set(session2.id, { browser: cdpBrowser, bunView: null, page: page2, engine: "cdp", cleanups: cleanups2, tokenBudget: { total: 0, used: 0 }, lastActivity: Date.now(), autoGallery: opts.autoGallery ?? false });
|
|
11261
|
-
return { session: session2, page: page2 };
|
|
11262
|
-
}
|
|
11263
|
-
const engine = opts.engine === "auto" || !opts.engine ? selectEngine(opts.useCase ?? "spa_navigate" /* SPA_NAVIGATE */, opts.engine) : opts.engine;
|
|
11264
|
-
const resolvedEngine = engine === "auto" ? "playwright" : engine;
|
|
11265
|
-
let browser = null;
|
|
11266
|
-
let bunView = null;
|
|
11267
|
-
let page;
|
|
11268
|
-
if (resolvedEngine === "bun") {
|
|
11269
|
-
if (!isBunWebViewAvailable()) {
|
|
11270
|
-
console.warn("[browser] Bun.WebView requested but not available \u2014 falling back to playwright. Run: bun upgrade --canary");
|
|
11271
|
-
browser = await launchPlaywright({ headless: opts.headless ?? true, viewport: opts.viewport, userAgent: opts.userAgent });
|
|
11272
|
-
page = await getPage(browser, { viewport: opts.viewport, userAgent: opts.userAgent });
|
|
11273
|
-
} else {
|
|
11274
|
-
bunView = new BunWebViewSession({
|
|
11275
|
-
width: opts.viewport?.width ?? 1280,
|
|
11276
|
-
height: opts.viewport?.height ?? 720,
|
|
11277
|
-
profile: opts.name ?? undefined
|
|
11278
|
-
});
|
|
11279
|
-
if (opts.stealth) {}
|
|
11280
|
-
page = createBunProxy(bunView);
|
|
11281
|
-
}
|
|
11282
|
-
} else if (resolvedEngine === "lightpanda") {
|
|
11283
|
-
browser = await connectLightpanda();
|
|
11284
|
-
const context = await browser.newContext({ viewport: opts.viewport ?? { width: 1280, height: 720 } });
|
|
11285
|
-
page = await context.newPage();
|
|
11286
|
-
} else {
|
|
11287
|
-
browser = await pool.acquire(opts.headless ?? true);
|
|
11288
|
-
if (opts.storageState) {
|
|
11289
|
-
const { loadStatePath: loadStatePath2 } = await Promise.resolve().then(() => (init_storage_state(), exports_storage_state));
|
|
11290
|
-
const statePath2 = loadStatePath2(opts.storageState);
|
|
11291
|
-
if (statePath2) {
|
|
11292
|
-
const context = await browser.newContext({
|
|
11293
|
-
viewport: opts.viewport ?? { width: 1280, height: 720 },
|
|
11294
|
-
userAgent: opts.userAgent,
|
|
11295
|
-
storageState: statePath2
|
|
11296
|
-
});
|
|
11297
|
-
page = await context.newPage();
|
|
11298
|
-
} else {
|
|
11299
|
-
page = await getPage(browser, { viewport: opts.viewport, userAgent: opts.userAgent });
|
|
11300
|
-
}
|
|
11301
|
-
} else {
|
|
11302
|
-
page = await getPage(browser, { viewport: opts.viewport, userAgent: opts.userAgent });
|
|
11303
|
-
}
|
|
11304
|
-
}
|
|
11305
|
-
const sessionName = opts.name ?? (opts.startUrl ? (() => {
|
|
11306
|
-
try {
|
|
11307
|
-
return new URL(opts.startUrl).hostname;
|
|
11308
|
-
} catch {
|
|
11309
|
-
return;
|
|
11310
|
-
}
|
|
11311
|
-
})() : undefined);
|
|
11312
|
-
const session = createSession({
|
|
11313
|
-
engine: bunView ? "bun" : browser ? resolvedEngine : resolvedEngine,
|
|
11314
|
-
projectId: opts.projectId,
|
|
11315
|
-
agentId: opts.agentId,
|
|
11316
|
-
startUrl: opts.startUrl,
|
|
11317
|
-
name: sessionName
|
|
11318
|
-
});
|
|
11319
|
-
if (opts.stealth && !bunView) {
|
|
11320
|
-
try {
|
|
11321
|
-
await applyStealthPatches(page);
|
|
11322
|
-
} catch {}
|
|
11323
|
-
}
|
|
11324
|
-
const cleanups = [];
|
|
11325
|
-
if (!bunView) {
|
|
11326
|
-
if (opts.captureNetwork !== false) {
|
|
11327
|
-
try {
|
|
11328
|
-
cleanups.push(enableNetworkLogging(page, session.id));
|
|
11329
|
-
} catch {}
|
|
11330
|
-
}
|
|
11331
|
-
if (opts.captureConsole !== false) {
|
|
11332
|
-
try {
|
|
11333
|
-
cleanups.push(enableConsoleCapture(page, session.id));
|
|
11334
|
-
} catch {}
|
|
11335
|
-
}
|
|
11336
|
-
try {
|
|
11337
|
-
cleanups.push(setupDialogHandler(page, session.id));
|
|
11338
|
-
} catch {}
|
|
11339
|
-
} else {
|
|
11340
|
-
if (opts.captureConsole !== false) {
|
|
11341
|
-
try {
|
|
11342
|
-
const { logConsoleMessage: logConsoleMessage2 } = await Promise.resolve().then(() => (init_console_log(), exports_console_log));
|
|
11343
|
-
await bunView.addInitScript(`
|
|
11344
|
-
(() => {
|
|
11345
|
-
const orig = { log: console.log, warn: console.warn, error: console.error, debug: console.debug, info: console.info };
|
|
11346
|
-
['log','warn','error','debug','info'].forEach(level => {
|
|
11347
|
-
console[level] = (...args) => {
|
|
11348
|
-
orig[level](...args);
|
|
11349
|
-
};
|
|
11350
|
-
});
|
|
11351
|
-
})()
|
|
11352
|
-
`);
|
|
11353
|
-
} catch {}
|
|
11354
|
-
}
|
|
11355
|
-
}
|
|
11356
|
-
handles.set(session.id, { browser, bunView, page, engine: bunView ? "bun" : resolvedEngine, cleanups, tokenBudget: { total: 0, used: 0 }, lastActivity: Date.now(), autoGallery: opts.autoGallery ?? false });
|
|
11357
|
-
if (opts.startUrl) {
|
|
11358
|
-
try {
|
|
11359
|
-
if (bunView) {
|
|
11360
|
-
await bunView.goto(opts.startUrl);
|
|
11361
|
-
} else {
|
|
11362
|
-
await page.goto(opts.startUrl, { waitUntil: "domcontentloaded" });
|
|
11363
|
-
}
|
|
11364
|
-
} catch {}
|
|
11365
|
-
}
|
|
11366
|
-
return { session, page };
|
|
11367
|
-
}
|
|
11368
|
-
function getSessionPage(sessionId) {
|
|
11369
|
-
const handle = handles.get(sessionId);
|
|
11370
|
-
if (!handle)
|
|
11371
|
-
throw new SessionNotFoundError(sessionId);
|
|
11372
|
-
try {
|
|
11373
|
-
if (handle.bunView) {
|
|
11374
|
-
handle.bunView.url();
|
|
11375
|
-
} else {
|
|
11376
|
-
handle.page.url();
|
|
11377
|
-
}
|
|
11378
|
-
} catch {
|
|
11379
|
-
handles.delete(sessionId);
|
|
11380
|
-
throw new SessionNotFoundError(sessionId);
|
|
11381
|
-
}
|
|
11382
|
-
handle.lastActivity = Date.now();
|
|
11383
|
-
return handle.page;
|
|
11384
|
-
}
|
|
11385
|
-
function getSessionBunView(sessionId) {
|
|
11386
|
-
return handles.get(sessionId)?.bunView ?? null;
|
|
11387
|
-
}
|
|
11388
|
-
function isBunSession(sessionId) {
|
|
11389
|
-
return handles.get(sessionId)?.engine === "bun";
|
|
11390
|
-
}
|
|
11391
|
-
function getSessionBrowser(sessionId) {
|
|
11392
|
-
const handle = handles.get(sessionId);
|
|
11393
|
-
if (!handle)
|
|
11394
|
-
throw new SessionNotFoundError(sessionId);
|
|
11395
|
-
if (!handle.browser)
|
|
11396
|
-
throw new BrowserError("This session uses Bun.WebView (no Playwright browser)", "NO_PLAYWRIGHT_BROWSER");
|
|
11397
|
-
return handle.browser;
|
|
11398
|
-
}
|
|
11399
|
-
function getSessionEngine(sessionId) {
|
|
11400
|
-
const handle = handles.get(sessionId);
|
|
11401
|
-
if (!handle)
|
|
11402
|
-
throw new SessionNotFoundError(sessionId);
|
|
11403
|
-
return handle.engine;
|
|
11404
|
-
}
|
|
11405
|
-
function hasActiveHandle(sessionId) {
|
|
11406
|
-
return handles.has(sessionId);
|
|
11407
|
-
}
|
|
11408
|
-
function setSessionPage(sessionId, page) {
|
|
11409
|
-
const handle = handles.get(sessionId);
|
|
11410
|
-
if (!handle)
|
|
11411
|
-
throw new SessionNotFoundError(sessionId);
|
|
11412
|
-
handle.page = page;
|
|
11413
|
-
}
|
|
11414
|
-
async function closeSession2(sessionId) {
|
|
11415
|
-
const handle = handles.get(sessionId);
|
|
11416
|
-
if (handle) {
|
|
11417
|
-
for (const cleanup of handle.cleanups) {
|
|
11418
|
-
try {
|
|
11419
|
-
cleanup();
|
|
11420
|
-
} catch {}
|
|
11421
|
-
}
|
|
11422
|
-
if (handle.bunView) {
|
|
11423
|
-
try {
|
|
11424
|
-
await handle.bunView.close();
|
|
11425
|
-
} catch {}
|
|
11426
|
-
} else {
|
|
11427
|
-
try {
|
|
11428
|
-
await handle.page.context().close();
|
|
11429
|
-
} catch {}
|
|
11430
|
-
if (handle.browser)
|
|
11431
|
-
pool.release(handle.browser);
|
|
11432
|
-
}
|
|
11433
|
-
handles.delete(sessionId);
|
|
11434
|
-
}
|
|
11435
|
-
return closeSession(sessionId);
|
|
11436
|
-
}
|
|
11437
|
-
function getSession2(sessionId) {
|
|
11438
|
-
return getSession(sessionId);
|
|
11439
|
-
}
|
|
11440
|
-
function listSessions2(filter) {
|
|
11441
|
-
return listSessions(filter);
|
|
11442
|
-
}
|
|
11443
|
-
function getActiveSessions() {
|
|
11444
|
-
return listSessions({ status: "active" });
|
|
11445
|
-
}
|
|
11446
|
-
async function closeAllSessions() {
|
|
11447
|
-
for (const [id] of handles) {
|
|
11448
|
-
await closeSession2(id).catch(() => {});
|
|
11449
|
-
}
|
|
11450
|
-
await pool.destroyAll();
|
|
11451
|
-
}
|
|
11452
|
-
function getSessionByName2(name) {
|
|
11453
|
-
return getSessionByName(name);
|
|
11454
|
-
}
|
|
11455
|
-
function renameSession2(id, name) {
|
|
11456
|
-
return renameSession(id, name);
|
|
11457
|
-
}
|
|
11458
|
-
function getTokenBudget(sessionId) {
|
|
11459
|
-
const handle = handles.get(sessionId);
|
|
11460
|
-
return handle ? handle.tokenBudget : null;
|
|
11461
|
-
}
|
|
11462
|
-
function getActiveSessionForAgent2(agentId) {
|
|
11463
|
-
const session = getActiveSessionForAgent(agentId);
|
|
11464
|
-
if (!session)
|
|
11465
|
-
return null;
|
|
11466
|
-
const handle = handles.get(session.id);
|
|
11467
|
-
if (!handle)
|
|
11468
|
-
return null;
|
|
11469
|
-
try {
|
|
11470
|
-
if (handle.bunView)
|
|
11471
|
-
handle.bunView.url();
|
|
11472
|
-
else
|
|
11473
|
-
handle.page.url();
|
|
11474
|
-
} catch {
|
|
11475
|
-
handles.delete(session.id);
|
|
11476
|
-
return null;
|
|
11477
|
-
}
|
|
11478
|
-
return { session, page: handle.page };
|
|
11479
|
-
}
|
|
11480
|
-
function getDefaultSession() {
|
|
11481
|
-
const session = getDefaultActiveSession();
|
|
11482
|
-
if (!session)
|
|
11483
|
-
return null;
|
|
11484
|
-
const handle = handles.get(session.id);
|
|
11485
|
-
if (!handle)
|
|
11486
|
-
return null;
|
|
11487
|
-
try {
|
|
11488
|
-
if (handle.bunView)
|
|
11489
|
-
handle.bunView.url();
|
|
11490
|
-
else
|
|
11491
|
-
handle.page.url();
|
|
11492
|
-
} catch {
|
|
11493
|
-
handles.delete(session.id);
|
|
11494
|
-
return null;
|
|
11495
|
-
}
|
|
11496
|
-
return { session, page: handle.page };
|
|
11497
|
-
}
|
|
11498
|
-
function isAutoGallery(sessionId) {
|
|
11499
|
-
return handles.get(sessionId)?.autoGallery ?? false;
|
|
11500
|
-
}
|
|
11501
|
-
function countActiveSessions2() {
|
|
11502
|
-
return countActiveSessions();
|
|
11503
|
-
}
|
|
11504
|
-
var handles, pool, SESSION_TTL_MS, ttlInterval;
|
|
11505
|
-
var init_session = __esm(() => {
|
|
11506
|
-
init_types();
|
|
11507
|
-
init_types();
|
|
11508
|
-
init_sessions();
|
|
11509
|
-
init_playwright();
|
|
11510
|
-
init_lightpanda();
|
|
11511
|
-
init_bun_webview();
|
|
11512
|
-
init_selector();
|
|
11513
|
-
init_network();
|
|
11514
|
-
init_console();
|
|
11515
|
-
init_stealth();
|
|
11516
|
-
init_dialogs();
|
|
11517
|
-
handles = new Map;
|
|
11518
|
-
pool = new BrowserPool(5);
|
|
11519
|
-
SESSION_TTL_MS = parseInt(process.env["SESSION_TTL_MINUTES"] ?? "10", 10) * 60000;
|
|
11520
|
-
ttlInterval = setInterval(async () => {
|
|
11521
|
-
const now = Date.now();
|
|
11522
|
-
for (const [id, handle] of handles) {
|
|
11523
|
-
if (now - handle.lastActivity > SESSION_TTL_MS) {
|
|
11524
|
-
try {
|
|
11525
|
-
await closeSession2(id);
|
|
11526
|
-
} catch {}
|
|
11527
|
-
}
|
|
11528
|
-
}
|
|
11529
|
-
}, 60000);
|
|
11530
|
-
if (ttlInterval.unref)
|
|
11531
|
-
ttlInterval.unref();
|
|
11532
|
-
});
|
|
11533
|
-
|
|
11534
11269
|
// src/lib/snapshot.ts
|
|
11535
11270
|
var exports_snapshot = {};
|
|
11536
11271
|
__export(exports_snapshot, {
|
|
@@ -11881,6 +11616,7 @@ __export(exports_actions, {
|
|
|
11881
11616
|
typeRef: () => typeRef,
|
|
11882
11617
|
type: () => type,
|
|
11883
11618
|
stopWatch: () => stopWatch,
|
|
11619
|
+
stopAllWatchesForSession: () => stopAllWatchesForSession,
|
|
11884
11620
|
selectRef: () => selectRef,
|
|
11885
11621
|
selectOption: () => selectOption,
|
|
11886
11622
|
scrollTo: () => scrollTo,
|
|
@@ -12207,6 +11943,12 @@ function stopWatch(watchId) {
|
|
|
12207
11943
|
activeWatches.delete(watchId);
|
|
12208
11944
|
}
|
|
12209
11945
|
}
|
|
11946
|
+
function stopAllWatchesForSession(_sessionId) {
|
|
11947
|
+
for (const [id, w] of activeWatches) {
|
|
11948
|
+
clearInterval(w.interval);
|
|
11949
|
+
activeWatches.delete(id);
|
|
11950
|
+
}
|
|
11951
|
+
}
|
|
12210
11952
|
async function clickRef(page, sessionId, ref, opts) {
|
|
12211
11953
|
try {
|
|
12212
11954
|
const locator = getRefLocator(page, sessionId, ref);
|
|
@@ -12282,6 +12024,396 @@ var init_actions = __esm(() => {
|
|
|
12282
12024
|
activeWatches = new Map;
|
|
12283
12025
|
});
|
|
12284
12026
|
|
|
12027
|
+
// src/lib/session.ts
|
|
12028
|
+
var exports_session = {};
|
|
12029
|
+
__export(exports_session, {
|
|
12030
|
+
setSessionPage: () => setSessionPage,
|
|
12031
|
+
renameSession: () => renameSession2,
|
|
12032
|
+
listSessions: () => listSessions2,
|
|
12033
|
+
isBunSession: () => isBunSession,
|
|
12034
|
+
isAutoGallery: () => isAutoGallery,
|
|
12035
|
+
hasActiveHandle: () => hasActiveHandle,
|
|
12036
|
+
getTokenBudget: () => getTokenBudget,
|
|
12037
|
+
getSessionPage: () => getSessionPage,
|
|
12038
|
+
getSessionEngine: () => getSessionEngine,
|
|
12039
|
+
getSessionByName: () => getSessionByName2,
|
|
12040
|
+
getSessionBunView: () => getSessionBunView,
|
|
12041
|
+
getSessionBrowser: () => getSessionBrowser,
|
|
12042
|
+
getSession: () => getSession2,
|
|
12043
|
+
getDefaultSession: () => getDefaultSession,
|
|
12044
|
+
getActiveSessions: () => getActiveSessions,
|
|
12045
|
+
getActiveSessionForAgent: () => getActiveSessionForAgent2,
|
|
12046
|
+
createSession: () => createSession2,
|
|
12047
|
+
countActiveSessions: () => countActiveSessions2,
|
|
12048
|
+
closeSession: () => closeSession2,
|
|
12049
|
+
closeAllSessions: () => closeAllSessions,
|
|
12050
|
+
browserPool: () => pool
|
|
12051
|
+
});
|
|
12052
|
+
function createBunProxy(view) {
|
|
12053
|
+
return view;
|
|
12054
|
+
}
|
|
12055
|
+
async function createSession2(opts = {}) {
|
|
12056
|
+
if (opts.cdpUrl) {
|
|
12057
|
+
const { connectToExistingBrowser: connectToExistingBrowser2 } = await Promise.resolve().then(() => (init_cdp(), exports_cdp));
|
|
12058
|
+
const cdpBrowser = await connectToExistingBrowser2(opts.cdpUrl);
|
|
12059
|
+
const contexts = cdpBrowser.contexts();
|
|
12060
|
+
const context = contexts.length > 0 ? contexts[0] : await cdpBrowser.newContext();
|
|
12061
|
+
const pages = context.pages();
|
|
12062
|
+
const page2 = pages.length > 0 ? pages[0] : await context.newPage();
|
|
12063
|
+
const session2 = createSession({
|
|
12064
|
+
engine: "cdp",
|
|
12065
|
+
projectId: opts.projectId,
|
|
12066
|
+
agentId: opts.agentId,
|
|
12067
|
+
startUrl: page2.url(),
|
|
12068
|
+
name: opts.name ?? "attached"
|
|
12069
|
+
});
|
|
12070
|
+
const cleanups2 = [];
|
|
12071
|
+
if (opts.captureNetwork !== false) {
|
|
12072
|
+
try {
|
|
12073
|
+
cleanups2.push(enableNetworkLogging(page2, session2.id));
|
|
12074
|
+
} catch {}
|
|
12075
|
+
}
|
|
12076
|
+
if (opts.captureConsole !== false) {
|
|
12077
|
+
try {
|
|
12078
|
+
cleanups2.push(enableConsoleCapture(page2, session2.id));
|
|
12079
|
+
} catch {}
|
|
12080
|
+
}
|
|
12081
|
+
try {
|
|
12082
|
+
cleanups2.push(setupDialogHandler(page2, session2.id));
|
|
12083
|
+
} catch {}
|
|
12084
|
+
handles.set(session2.id, { browser: cdpBrowser, bunView: null, tuiSession: null, page: page2, engine: "cdp", cleanups: cleanups2, tokenBudget: { total: 0, used: 0 }, lastActivity: Date.now(), autoGallery: opts.autoGallery ?? false });
|
|
12085
|
+
return { session: session2, page: page2 };
|
|
12086
|
+
}
|
|
12087
|
+
const engine = opts.engine === "auto" || !opts.engine ? selectEngine(opts.useCase ?? "spa_navigate" /* SPA_NAVIGATE */, opts.engine) : opts.engine;
|
|
12088
|
+
const resolvedEngine = engine === "auto" ? "playwright" : engine;
|
|
12089
|
+
let browser = null;
|
|
12090
|
+
let bunView = null;
|
|
12091
|
+
let page;
|
|
12092
|
+
if (resolvedEngine === "bun") {
|
|
12093
|
+
if (!isBunWebViewAvailable()) {
|
|
12094
|
+
console.warn("[browser] Bun.WebView requested but not available \u2014 falling back to playwright. Run: bun upgrade --canary");
|
|
12095
|
+
browser = await launchPlaywright({ headless: opts.headless ?? true, viewport: opts.viewport, userAgent: opts.userAgent });
|
|
12096
|
+
page = await getPage(browser, { viewport: opts.viewport, userAgent: opts.userAgent });
|
|
12097
|
+
} else {
|
|
12098
|
+
bunView = new BunWebViewSession({
|
|
12099
|
+
width: opts.viewport?.width ?? 1280,
|
|
12100
|
+
height: opts.viewport?.height ?? 720,
|
|
12101
|
+
profile: opts.name ?? undefined
|
|
12102
|
+
});
|
|
12103
|
+
if (opts.stealth) {}
|
|
12104
|
+
page = createBunProxy(bunView);
|
|
12105
|
+
}
|
|
12106
|
+
} else if (resolvedEngine === "lightpanda") {
|
|
12107
|
+
browser = await connectLightpanda();
|
|
12108
|
+
const context = await browser.newContext({ viewport: opts.viewport ?? { width: 1280, height: 720 } });
|
|
12109
|
+
page = await context.newPage();
|
|
12110
|
+
} else if (resolvedEngine === "tui") {
|
|
12111
|
+
const command = opts.startUrl ?? "bash";
|
|
12112
|
+
const tuiSess = await launchTui(command, {
|
|
12113
|
+
headless: opts.headless ?? true,
|
|
12114
|
+
viewport: opts.viewport
|
|
12115
|
+
});
|
|
12116
|
+
browser = tuiSess.browser;
|
|
12117
|
+
page = tuiSess.page;
|
|
12118
|
+
const session2 = createSession({
|
|
12119
|
+
engine: "tui",
|
|
12120
|
+
projectId: opts.projectId,
|
|
12121
|
+
agentId: opts.agentId,
|
|
12122
|
+
startUrl: opts.startUrl,
|
|
12123
|
+
name: opts.name ?? "tui"
|
|
12124
|
+
});
|
|
12125
|
+
const cleanups2 = [];
|
|
12126
|
+
cleanups2.push(() => closeTui(tuiSess));
|
|
12127
|
+
if (opts.captureNetwork !== false) {
|
|
12128
|
+
try {
|
|
12129
|
+
cleanups2.push(enableNetworkLogging(page, session2.id));
|
|
12130
|
+
} catch {}
|
|
12131
|
+
}
|
|
12132
|
+
if (opts.captureConsole !== false) {
|
|
12133
|
+
try {
|
|
12134
|
+
cleanups2.push(enableConsoleCapture(page, session2.id));
|
|
12135
|
+
} catch {}
|
|
12136
|
+
}
|
|
12137
|
+
try {
|
|
12138
|
+
cleanups2.push(setupDialogHandler(page, session2.id));
|
|
12139
|
+
} catch {}
|
|
12140
|
+
handles.set(session2.id, { browser, bunView: null, tuiSession: tuiSess, page, engine: "tui", cleanups: cleanups2, tokenBudget: { total: 0, used: 0 }, lastActivity: Date.now(), autoGallery: opts.autoGallery ?? false });
|
|
12141
|
+
return { session: session2, page };
|
|
12142
|
+
} else {
|
|
12143
|
+
browser = await pool.acquire(opts.headless ?? true);
|
|
12144
|
+
if (opts.storageState) {
|
|
12145
|
+
const { loadStatePath: loadStatePath2 } = await Promise.resolve().then(() => (init_storage_state(), exports_storage_state));
|
|
12146
|
+
const statePath2 = loadStatePath2(opts.storageState);
|
|
12147
|
+
if (statePath2) {
|
|
12148
|
+
const context = await browser.newContext({
|
|
12149
|
+
viewport: opts.viewport ?? { width: 1280, height: 720 },
|
|
12150
|
+
userAgent: opts.userAgent,
|
|
12151
|
+
storageState: statePath2
|
|
12152
|
+
});
|
|
12153
|
+
page = await context.newPage();
|
|
12154
|
+
} else {
|
|
12155
|
+
page = await getPage(browser, { viewport: opts.viewport, userAgent: opts.userAgent });
|
|
12156
|
+
}
|
|
12157
|
+
} else {
|
|
12158
|
+
page = await getPage(browser, { viewport: opts.viewport, userAgent: opts.userAgent });
|
|
12159
|
+
}
|
|
12160
|
+
}
|
|
12161
|
+
const sessionName = opts.name ?? (opts.startUrl ? (() => {
|
|
12162
|
+
try {
|
|
12163
|
+
return new URL(opts.startUrl).hostname;
|
|
12164
|
+
} catch {
|
|
12165
|
+
return;
|
|
12166
|
+
}
|
|
12167
|
+
})() : undefined);
|
|
12168
|
+
const session = createSession({
|
|
12169
|
+
engine: bunView ? "bun" : browser ? resolvedEngine : resolvedEngine,
|
|
12170
|
+
projectId: opts.projectId,
|
|
12171
|
+
agentId: opts.agentId,
|
|
12172
|
+
startUrl: opts.startUrl,
|
|
12173
|
+
name: sessionName
|
|
12174
|
+
});
|
|
12175
|
+
if (opts.stealth && !bunView) {
|
|
12176
|
+
try {
|
|
12177
|
+
await applyStealthPatches(page);
|
|
12178
|
+
} catch {}
|
|
12179
|
+
}
|
|
12180
|
+
const cleanups = [];
|
|
12181
|
+
if (!bunView) {
|
|
12182
|
+
if (opts.captureNetwork !== false) {
|
|
12183
|
+
try {
|
|
12184
|
+
cleanups.push(enableNetworkLogging(page, session.id));
|
|
12185
|
+
} catch {}
|
|
12186
|
+
}
|
|
12187
|
+
if (opts.captureConsole !== false) {
|
|
12188
|
+
try {
|
|
12189
|
+
cleanups.push(enableConsoleCapture(page, session.id));
|
|
12190
|
+
} catch {}
|
|
12191
|
+
}
|
|
12192
|
+
try {
|
|
12193
|
+
cleanups.push(setupDialogHandler(page, session.id));
|
|
12194
|
+
} catch {}
|
|
12195
|
+
} else {
|
|
12196
|
+
if (opts.captureConsole !== false) {
|
|
12197
|
+
try {
|
|
12198
|
+
const { logConsoleMessage: logConsoleMessage2 } = await Promise.resolve().then(() => (init_console_log(), exports_console_log));
|
|
12199
|
+
await bunView.addInitScript(`
|
|
12200
|
+
(() => {
|
|
12201
|
+
const orig = { log: console.log, warn: console.warn, error: console.error, debug: console.debug, info: console.info };
|
|
12202
|
+
['log','warn','error','debug','info'].forEach(level => {
|
|
12203
|
+
console[level] = (...args) => {
|
|
12204
|
+
orig[level](...args);
|
|
12205
|
+
};
|
|
12206
|
+
});
|
|
12207
|
+
})()
|
|
12208
|
+
`);
|
|
12209
|
+
} catch {}
|
|
12210
|
+
}
|
|
12211
|
+
}
|
|
12212
|
+
handles.set(session.id, { browser, bunView, tuiSession: null, page, engine: bunView ? "bun" : resolvedEngine, cleanups, tokenBudget: { total: 0, used: 0 }, lastActivity: Date.now(), autoGallery: opts.autoGallery ?? false });
|
|
12213
|
+
if (opts.startUrl) {
|
|
12214
|
+
try {
|
|
12215
|
+
if (bunView) {
|
|
12216
|
+
await bunView.goto(opts.startUrl);
|
|
12217
|
+
} else {
|
|
12218
|
+
await page.goto(opts.startUrl, { waitUntil: "domcontentloaded" });
|
|
12219
|
+
}
|
|
12220
|
+
} catch {}
|
|
12221
|
+
}
|
|
12222
|
+
return { session, page };
|
|
12223
|
+
}
|
|
12224
|
+
function getSessionPage(sessionId) {
|
|
12225
|
+
const handle = handles.get(sessionId);
|
|
12226
|
+
if (!handle)
|
|
12227
|
+
throw new SessionNotFoundError(sessionId);
|
|
12228
|
+
try {
|
|
12229
|
+
if (handle.bunView) {
|
|
12230
|
+
handle.bunView.url();
|
|
12231
|
+
} else {
|
|
12232
|
+
handle.page.url();
|
|
12233
|
+
}
|
|
12234
|
+
} catch {
|
|
12235
|
+
handles.delete(sessionId);
|
|
12236
|
+
throw new SessionNotFoundError(sessionId);
|
|
12237
|
+
}
|
|
12238
|
+
handle.lastActivity = Date.now();
|
|
12239
|
+
return handle.page;
|
|
12240
|
+
}
|
|
12241
|
+
function getSessionBunView(sessionId) {
|
|
12242
|
+
return handles.get(sessionId)?.bunView ?? null;
|
|
12243
|
+
}
|
|
12244
|
+
function isBunSession(sessionId) {
|
|
12245
|
+
return handles.get(sessionId)?.engine === "bun";
|
|
12246
|
+
}
|
|
12247
|
+
function getSessionBrowser(sessionId) {
|
|
12248
|
+
const handle = handles.get(sessionId);
|
|
12249
|
+
if (!handle)
|
|
12250
|
+
throw new SessionNotFoundError(sessionId);
|
|
12251
|
+
if (!handle.browser)
|
|
12252
|
+
throw new BrowserError("This session uses Bun.WebView (no Playwright browser)", "NO_PLAYWRIGHT_BROWSER");
|
|
12253
|
+
return handle.browser;
|
|
12254
|
+
}
|
|
12255
|
+
function getSessionEngine(sessionId) {
|
|
12256
|
+
const handle = handles.get(sessionId);
|
|
12257
|
+
if (!handle)
|
|
12258
|
+
throw new SessionNotFoundError(sessionId);
|
|
12259
|
+
return handle.engine;
|
|
12260
|
+
}
|
|
12261
|
+
function hasActiveHandle(sessionId) {
|
|
12262
|
+
return handles.has(sessionId);
|
|
12263
|
+
}
|
|
12264
|
+
function setSessionPage(sessionId, page) {
|
|
12265
|
+
const handle = handles.get(sessionId);
|
|
12266
|
+
if (!handle)
|
|
12267
|
+
throw new SessionNotFoundError(sessionId);
|
|
12268
|
+
handle.page = page;
|
|
12269
|
+
}
|
|
12270
|
+
async function closeSession2(sessionId) {
|
|
12271
|
+
const handle = handles.get(sessionId);
|
|
12272
|
+
if (handle) {
|
|
12273
|
+
for (const cleanup of handle.cleanups) {
|
|
12274
|
+
try {
|
|
12275
|
+
cleanup();
|
|
12276
|
+
} catch {}
|
|
12277
|
+
}
|
|
12278
|
+
if (handle.bunView) {
|
|
12279
|
+
try {
|
|
12280
|
+
await handle.bunView.close();
|
|
12281
|
+
} catch {}
|
|
12282
|
+
} else if (handle.tuiSession) {} else {
|
|
12283
|
+
try {
|
|
12284
|
+
await handle.page.context().close();
|
|
12285
|
+
} catch {}
|
|
12286
|
+
if (handle.browser)
|
|
12287
|
+
pool.release(handle.browser);
|
|
12288
|
+
}
|
|
12289
|
+
handles.delete(sessionId);
|
|
12290
|
+
}
|
|
12291
|
+
try {
|
|
12292
|
+
const { clearLastSnapshot: clearLastSnapshot2, clearSessionRefs: clearSessionRefs2 } = await Promise.resolve().then(() => (init_snapshot(), exports_snapshot));
|
|
12293
|
+
clearLastSnapshot2(sessionId);
|
|
12294
|
+
clearSessionRefs2(sessionId);
|
|
12295
|
+
} catch {}
|
|
12296
|
+
try {
|
|
12297
|
+
const { stopAllWatchesForSession: stopAllWatchesForSession2 } = await Promise.resolve().then(() => (init_actions(), exports_actions));
|
|
12298
|
+
stopAllWatchesForSession2(sessionId);
|
|
12299
|
+
} catch {}
|
|
12300
|
+
try {
|
|
12301
|
+
const { clearDialogs: clearDialogs2 } = await Promise.resolve().then(() => (init_dialogs(), exports_dialogs));
|
|
12302
|
+
clearDialogs2(sessionId);
|
|
12303
|
+
} catch {}
|
|
12304
|
+
return closeSession(sessionId);
|
|
12305
|
+
}
|
|
12306
|
+
function getSession2(sessionId) {
|
|
12307
|
+
return getSession(sessionId);
|
|
12308
|
+
}
|
|
12309
|
+
function listSessions2(filter) {
|
|
12310
|
+
return listSessions(filter);
|
|
12311
|
+
}
|
|
12312
|
+
function getActiveSessions() {
|
|
12313
|
+
return listSessions({ status: "active" });
|
|
12314
|
+
}
|
|
12315
|
+
async function closeAllSessions() {
|
|
12316
|
+
for (const [id] of handles) {
|
|
12317
|
+
await closeSession2(id).catch(() => {});
|
|
12318
|
+
}
|
|
12319
|
+
await pool.destroyAll();
|
|
12320
|
+
}
|
|
12321
|
+
function getSessionByName2(name) {
|
|
12322
|
+
return getSessionByName(name);
|
|
12323
|
+
}
|
|
12324
|
+
function renameSession2(id, name) {
|
|
12325
|
+
return renameSession(id, name);
|
|
12326
|
+
}
|
|
12327
|
+
function getTokenBudget(sessionId) {
|
|
12328
|
+
const handle = handles.get(sessionId);
|
|
12329
|
+
return handle ? handle.tokenBudget : null;
|
|
12330
|
+
}
|
|
12331
|
+
function getActiveSessionForAgent2(agentId) {
|
|
12332
|
+
const session = getActiveSessionForAgent(agentId);
|
|
12333
|
+
if (!session)
|
|
12334
|
+
return null;
|
|
12335
|
+
const handle = handles.get(session.id);
|
|
12336
|
+
if (!handle)
|
|
12337
|
+
return null;
|
|
12338
|
+
try {
|
|
12339
|
+
if (handle.bunView)
|
|
12340
|
+
handle.bunView.url();
|
|
12341
|
+
else
|
|
12342
|
+
handle.page.url();
|
|
12343
|
+
} catch {
|
|
12344
|
+
handles.delete(session.id);
|
|
12345
|
+
return null;
|
|
12346
|
+
}
|
|
12347
|
+
return { session, page: handle.page };
|
|
12348
|
+
}
|
|
12349
|
+
function getDefaultSession() {
|
|
12350
|
+
const session = getDefaultActiveSession();
|
|
12351
|
+
if (!session)
|
|
12352
|
+
return null;
|
|
12353
|
+
const handle = handles.get(session.id);
|
|
12354
|
+
if (!handle)
|
|
12355
|
+
return null;
|
|
12356
|
+
try {
|
|
12357
|
+
if (handle.bunView)
|
|
12358
|
+
handle.bunView.url();
|
|
12359
|
+
else
|
|
12360
|
+
handle.page.url();
|
|
12361
|
+
} catch {
|
|
12362
|
+
handles.delete(session.id);
|
|
12363
|
+
return null;
|
|
12364
|
+
}
|
|
12365
|
+
return { session, page: handle.page };
|
|
12366
|
+
}
|
|
12367
|
+
function isAutoGallery(sessionId) {
|
|
12368
|
+
return handles.get(sessionId)?.autoGallery ?? false;
|
|
12369
|
+
}
|
|
12370
|
+
function countActiveSessions2() {
|
|
12371
|
+
return countActiveSessions();
|
|
12372
|
+
}
|
|
12373
|
+
var handles, pool, SESSION_TTL_MS, ttlInterval, DB_PRUNE_INTERVAL_MS, DB_RETENTION_HOURS = 24, dbPruneInterval;
|
|
12374
|
+
var init_session = __esm(() => {
|
|
12375
|
+
init_types();
|
|
12376
|
+
init_types();
|
|
12377
|
+
init_sessions();
|
|
12378
|
+
init_playwright();
|
|
12379
|
+
init_lightpanda();
|
|
12380
|
+
init_bun_webview();
|
|
12381
|
+
init_selector();
|
|
12382
|
+
init_tui();
|
|
12383
|
+
init_network();
|
|
12384
|
+
init_console();
|
|
12385
|
+
init_stealth();
|
|
12386
|
+
init_dialogs();
|
|
12387
|
+
handles = new Map;
|
|
12388
|
+
pool = new BrowserPool(5);
|
|
12389
|
+
SESSION_TTL_MS = parseInt(process.env["SESSION_TTL_MINUTES"] ?? "10", 10) * 60000;
|
|
12390
|
+
ttlInterval = setInterval(async () => {
|
|
12391
|
+
const now = Date.now();
|
|
12392
|
+
for (const [id, handle] of handles) {
|
|
12393
|
+
if (now - handle.lastActivity > SESSION_TTL_MS) {
|
|
12394
|
+
try {
|
|
12395
|
+
await closeSession2(id);
|
|
12396
|
+
} catch {}
|
|
12397
|
+
}
|
|
12398
|
+
}
|
|
12399
|
+
}, 60000);
|
|
12400
|
+
if (ttlInterval.unref)
|
|
12401
|
+
ttlInterval.unref();
|
|
12402
|
+
DB_PRUNE_INTERVAL_MS = 30 * 60000;
|
|
12403
|
+
dbPruneInterval = setInterval(() => {
|
|
12404
|
+
try {
|
|
12405
|
+
const { getDatabase: getDatabase2 } = (init_schema(), __toCommonJS(exports_schema));
|
|
12406
|
+
const db = getDatabase2();
|
|
12407
|
+
const cutoff = new Date(Date.now() - DB_RETENTION_HOURS * 3600000).toISOString();
|
|
12408
|
+
db.prepare("DELETE FROM network_log WHERE session_id IN (SELECT id FROM sessions WHERE status != 'active') AND timestamp < ?").run(cutoff);
|
|
12409
|
+
db.prepare("DELETE FROM console_log WHERE session_id IN (SELECT id FROM sessions WHERE status != 'active') AND timestamp < ?").run(cutoff);
|
|
12410
|
+
db.prepare("DELETE FROM snapshots WHERE session_id IN (SELECT id FROM sessions WHERE status != 'active') AND timestamp < ?").run(cutoff);
|
|
12411
|
+
} catch {}
|
|
12412
|
+
}, DB_PRUNE_INTERVAL_MS);
|
|
12413
|
+
if (dbPruneInterval.unref)
|
|
12414
|
+
dbPruneInterval.unref();
|
|
12415
|
+
});
|
|
12416
|
+
|
|
12285
12417
|
// src/lib/extractor.ts
|
|
12286
12418
|
var exports_extractor = {};
|
|
12287
12419
|
__export(exports_extractor, {
|
|
@@ -23975,8 +24107,8 @@ import { join as join33 } from "path";
|
|
|
23975
24107
|
import { existsSync as existsSync43, mkdirSync as mkdirSync4, readFileSync as readFileSync33, writeFileSync as writeFileSync33 } from "fs";
|
|
23976
24108
|
import { homedir as homedir33 } from "os";
|
|
23977
24109
|
import { join as join43 } from "path";
|
|
23978
|
-
function
|
|
23979
|
-
this[name] =
|
|
24110
|
+
function __exportSetter2(name, newValue) {
|
|
24111
|
+
this[name] = __returnValue2.bind(null, newValue);
|
|
23980
24112
|
}
|
|
23981
24113
|
function isInMemoryDb(path) {
|
|
23982
24114
|
return path === ":memory:" || path.startsWith("file::memory:");
|
|
@@ -27090,13 +27222,13 @@ function clearActiveModel() {
|
|
|
27090
27222
|
delete config.activeModel;
|
|
27091
27223
|
writeConfig(config);
|
|
27092
27224
|
}
|
|
27093
|
-
var __defProp3,
|
|
27225
|
+
var __defProp3, __returnValue2 = (v) => v, __export3 = (target, all) => {
|
|
27094
27226
|
for (var name in all)
|
|
27095
27227
|
__defProp3(target, name, {
|
|
27096
27228
|
get: all[name],
|
|
27097
27229
|
enumerable: true,
|
|
27098
27230
|
configurable: true,
|
|
27099
|
-
set:
|
|
27231
|
+
set: __exportSetter2.bind(all, name)
|
|
27100
27232
|
});
|
|
27101
27233
|
}, __esm3 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), exports_database, MIGRATIONS, _db2 = null, init_database, AgentConflictError, EntityNotFoundError, MemoryNotFoundError, DuplicateMemoryError, MemoryExpiredError, InvalidScopeError, VersionConflictError, MemoryConflictError, OPENAI_EMBED_URL = "https://api.openai.com/v1/embeddings", EMBED_MODEL = "text-embedding-3-small", EMBED_DIMENSIONS = 1536, REDACTED = "[REDACTED]", SECRET_PATTERNS, _idCounter = 0, hookRegistry, INSTRUCTION_PATTERNS, PROMOTIONAL_PATTERNS, RECALL_PROMOTE_THRESHOLD = 3, CONFLICT_WINDOW_MS, MEMORY_WRITE_TTL = 30, MemoryLockConflictError, sessionFocus, STOP_WORDS, DEFAULT_CONFIG, VALID_SCOPES, VALID_CATEGORIES, defaultSyncAgents, DEFAULT_AUTO_MEMORY_CONFIG, MEMORY_EXTRACTION_SYSTEM_PROMPT = `You are a precise memory extraction engine for an AI agent.
|
|
27102
27234
|
Given text, extract facts worth remembering as structured JSON.
|
|
@@ -28477,6 +28609,11 @@ async function rememberPage(url, facts, tags) {
|
|
|
28477
28609
|
return;
|
|
28478
28610
|
} catch {}
|
|
28479
28611
|
}
|
|
28612
|
+
if (inMemoryCache.size >= MEMORY_MAX_SIZE && !inMemoryCache.has(key)) {
|
|
28613
|
+
const firstKey = inMemoryCache.keys().next().value;
|
|
28614
|
+
if (firstKey)
|
|
28615
|
+
inMemoryCache.delete(firstKey);
|
|
28616
|
+
}
|
|
28480
28617
|
inMemoryCache.set(key, {
|
|
28481
28618
|
data: memory,
|
|
28482
28619
|
expires: Date.now() + DEFAULT_TTL_HOURS * 60 * 60 * 1000
|
|
@@ -28506,9 +28643,18 @@ async function forgetPage(url) {
|
|
|
28506
28643
|
const key = cacheKey(url);
|
|
28507
28644
|
inMemoryCache.delete(key);
|
|
28508
28645
|
}
|
|
28509
|
-
var MEMORY_KEY_PREFIX = "browser-page:", DEFAULT_TTL_HOURS = 24, inMemoryCache;
|
|
28646
|
+
var MEMORY_KEY_PREFIX = "browser-page:", DEFAULT_TTL_HOURS = 24, inMemoryCache, MEMORY_MAX_SIZE = 200, _memorySweeper;
|
|
28510
28647
|
var init_page_memory = __esm(() => {
|
|
28511
28648
|
inMemoryCache = new Map;
|
|
28649
|
+
_memorySweeper = setInterval(() => {
|
|
28650
|
+
const now2 = Date.now();
|
|
28651
|
+
for (const [key, entry] of inMemoryCache) {
|
|
28652
|
+
if (entry.expires <= now2)
|
|
28653
|
+
inMemoryCache.delete(key);
|
|
28654
|
+
}
|
|
28655
|
+
}, 300000);
|
|
28656
|
+
if (_memorySweeper.unref)
|
|
28657
|
+
_memorySweeper.unref();
|
|
28512
28658
|
});
|
|
28513
28659
|
|
|
28514
28660
|
// node_modules/@hasna/conversations/dist/index.js
|
|
@@ -28605,11 +28751,11 @@ import { randomUUID as randomUUID22 } from "crypto";
|
|
|
28605
28751
|
import { readFileSync as readFileSync24, writeFileSync as writeFileSync7, mkdirSync as mkdirSync34 } from "fs";
|
|
28606
28752
|
import { join as join44, dirname as dirname24 } from "path";
|
|
28607
28753
|
import { homedir as homedir42 } from "os";
|
|
28608
|
-
function
|
|
28754
|
+
function __accessProp2(key) {
|
|
28609
28755
|
return this[key];
|
|
28610
28756
|
}
|
|
28611
|
-
function
|
|
28612
|
-
this[name] =
|
|
28757
|
+
function __exportSetter3(name, newValue) {
|
|
28758
|
+
this[name] = __returnValue3.bind(null, newValue);
|
|
28613
28759
|
}
|
|
28614
28760
|
function getDbPath3() {
|
|
28615
28761
|
if (process.env.CONVERSATIONS_DB_PATH)
|
|
@@ -30594,10 +30740,10 @@ function getGraphStats() {
|
|
|
30594
30740
|
map[r.relation] = r.c;
|
|
30595
30741
|
return { total_edges: total, by_relation: map };
|
|
30596
30742
|
}
|
|
30597
|
-
var __create3, __getProtoOf3, __defProp4, __getOwnPropNames3, __getOwnPropDesc2, __hasOwnProp3,
|
|
30743
|
+
var __create3, __getProtoOf3, __defProp4, __getOwnPropNames3, __getOwnPropDesc2, __hasOwnProp3, __toESMCache_node2, __toESMCache_esm2, __toESM3 = (mod, isNodeMode, target) => {
|
|
30598
30744
|
var canCache = mod != null && typeof mod === "object";
|
|
30599
30745
|
if (canCache) {
|
|
30600
|
-
var cache = isNodeMode ?
|
|
30746
|
+
var cache = isNodeMode ? __toESMCache_node2 ??= new WeakMap : __toESMCache_esm2 ??= new WeakMap;
|
|
30601
30747
|
var cached = cache.get(mod);
|
|
30602
30748
|
if (cached)
|
|
30603
30749
|
return cached;
|
|
@@ -30607,7 +30753,7 @@ var __create3, __getProtoOf3, __defProp4, __getOwnPropNames3, __getOwnPropDesc2,
|
|
|
30607
30753
|
for (let key of __getOwnPropNames3(mod))
|
|
30608
30754
|
if (!__hasOwnProp3.call(to, key))
|
|
30609
30755
|
__defProp4(to, key, {
|
|
30610
|
-
get:
|
|
30756
|
+
get: __accessProp2.bind(mod, key),
|
|
30611
30757
|
enumerable: true
|
|
30612
30758
|
});
|
|
30613
30759
|
if (canCache)
|
|
@@ -30622,19 +30768,19 @@ var __create3, __getProtoOf3, __defProp4, __getOwnPropNames3, __getOwnPropDesc2,
|
|
|
30622
30768
|
for (var key of __getOwnPropNames3(from))
|
|
30623
30769
|
if (!__hasOwnProp3.call(entry, key))
|
|
30624
30770
|
__defProp4(entry, key, {
|
|
30625
|
-
get:
|
|
30771
|
+
get: __accessProp2.bind(from, key),
|
|
30626
30772
|
enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable
|
|
30627
30773
|
});
|
|
30628
30774
|
}
|
|
30629
30775
|
__moduleCache2.set(from, entry);
|
|
30630
30776
|
return entry;
|
|
30631
|
-
}, __moduleCache2, __commonJS3 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports),
|
|
30777
|
+
}, __moduleCache2, __commonJS3 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports), __returnValue3 = (v) => v, __export4 = (target, all) => {
|
|
30632
30778
|
for (var name in all)
|
|
30633
30779
|
__defProp4(target, name, {
|
|
30634
30780
|
get: all[name],
|
|
30635
30781
|
enumerable: true,
|
|
30636
30782
|
configurable: true,
|
|
30637
|
-
set:
|
|
30783
|
+
set: __exportSetter3.bind(all, name)
|
|
30638
30784
|
});
|
|
30639
30785
|
}, exports_db, db = null, init_db = () => {}, require_react_development, require_react, cachedConfig = null, configLoadedAt = 0, CONFIG_CACHE_MS = 1e4, import_react, AGENT_NAMES, AGENT_ID_FILE, cachedAutoName = null, ONLINE_THRESHOLD_SECONDS = 60, CONFLICT_THRESHOLD_SECONDS, DEFAULT_LOCK_EXPIRY_MS, STALE_HEARTBEAT_SECONDS, STOPWORDS;
|
|
30640
30786
|
var init_dist4 = __esm(() => {
|
|
@@ -32972,6 +33118,11 @@ async function announceNavigation(url, sessionId, agentName = "browser-agent") {
|
|
|
32972
33118
|
await sdk.sendMessage(SPACE_NAME, `\uD83C\uDF10 Navigating to ${hostname} (session: ${sessionId.slice(0, 8)})`);
|
|
32973
33119
|
} catch {}
|
|
32974
33120
|
}
|
|
33121
|
+
if (activeNavigations.size >= NAV_MAX_SIZE && !activeNavigations.has(hostname)) {
|
|
33122
|
+
const firstKey = activeNavigations.keys().next().value;
|
|
33123
|
+
if (firstKey)
|
|
33124
|
+
activeNavigations.delete(firstKey);
|
|
33125
|
+
}
|
|
32975
33126
|
activeNavigations.set(hostname, { agentName, timestamp: Date.now() });
|
|
32976
33127
|
}
|
|
32977
33128
|
async function checkDuplicate2(url) {
|
|
@@ -33007,10 +33158,19 @@ async function checkDuplicate2(url) {
|
|
|
33007
33158
|
}
|
|
33008
33159
|
return { is_duplicate: false };
|
|
33009
33160
|
}
|
|
33010
|
-
var SPACE_NAME = "browser", DUPLICATE_WINDOW_MS, activeNavigations;
|
|
33161
|
+
var SPACE_NAME = "browser", DUPLICATE_WINDOW_MS, activeNavigations, NAV_MAX_SIZE = 200, _navSweeper;
|
|
33011
33162
|
var init_coordination = __esm(() => {
|
|
33012
33163
|
DUPLICATE_WINDOW_MS = 5 * 60 * 1000;
|
|
33013
33164
|
activeNavigations = new Map;
|
|
33165
|
+
_navSweeper = setInterval(() => {
|
|
33166
|
+
const cutoff = Date.now() - DUPLICATE_WINDOW_MS;
|
|
33167
|
+
for (const [key, entry] of activeNavigations) {
|
|
33168
|
+
if (entry.timestamp < cutoff)
|
|
33169
|
+
activeNavigations.delete(key);
|
|
33170
|
+
}
|
|
33171
|
+
}, 120000);
|
|
33172
|
+
if (_navSweeper.unref)
|
|
33173
|
+
_navSweeper.unref();
|
|
33014
33174
|
});
|
|
33015
33175
|
|
|
33016
33176
|
// node_modules/@hasna/todos/dist/index.js
|
|
@@ -33234,7 +33394,7 @@ import { existsSync as existsSync62 } from "fs";
|
|
|
33234
33394
|
import { join as join62 } from "path";
|
|
33235
33395
|
import { readFileSync as readFileSync43, statSync as statSync22 } from "fs";
|
|
33236
33396
|
import { relative as relative2, resolve as resolve23, join as join72 } from "path";
|
|
33237
|
-
import { execSync as
|
|
33397
|
+
import { execSync as execSync3 } from "child_process";
|
|
33238
33398
|
|
|
33239
33399
|
class TodosClient {
|
|
33240
33400
|
baseUrl;
|
|
@@ -37582,7 +37742,7 @@ function parseGitHubUrl(url) {
|
|
|
37582
37742
|
return { owner: match[1], repo: match[2], number: parseInt(match[3], 10) };
|
|
37583
37743
|
}
|
|
37584
37744
|
function fetchGitHubIssue(owner, repo, number) {
|
|
37585
|
-
const json2 =
|
|
37745
|
+
const json2 = execSync3(`gh api repos/${owner}/${repo}/issues/${number}`, { encoding: "utf-8", timeout: 15000 });
|
|
37586
37746
|
const data = JSON.parse(json2);
|
|
37587
37747
|
return {
|
|
37588
37748
|
number: data.number,
|
|
@@ -38613,6 +38773,8 @@ Skill: ${task.skill}` : ""}`,
|
|
|
38613
38773
|
};
|
|
38614
38774
|
} catch {}
|
|
38615
38775
|
}
|
|
38776
|
+
if (inMemoryQueue.length >= QUEUE_MAX_SIZE)
|
|
38777
|
+
inMemoryQueue.shift();
|
|
38616
38778
|
const id = `btask-${Date.now()}`;
|
|
38617
38779
|
const entry = { ...task, id, status: "pending", created_at: new Date().toISOString() };
|
|
38618
38780
|
inMemoryQueue.push(entry);
|
|
@@ -38646,7 +38808,7 @@ async function completeBrowserTask(taskId, result) {
|
|
|
38646
38808
|
if (idx >= 0)
|
|
38647
38809
|
inMemoryQueue.splice(idx, 1);
|
|
38648
38810
|
}
|
|
38649
|
-
var inMemoryQueue;
|
|
38811
|
+
var QUEUE_MAX_SIZE = 100, inMemoryQueue;
|
|
38650
38812
|
var init_task_queue = __esm(() => {
|
|
38651
38813
|
inMemoryQueue = [];
|
|
38652
38814
|
});
|
|
@@ -43645,7 +43807,7 @@ function resolveSessionId(sessionId) {
|
|
|
43645
43807
|
// src/mcp/sessions.ts
|
|
43646
43808
|
function register(server) {
|
|
43647
43809
|
server.tool("browser_session_create", "Create a new browser session. If agent_id is set and already has an active session, returns the existing one (use force_new to override). If session_id is omitted on other tools, the single active session is auto-selected. Use cdp_url to attach to an already-running Chrome instance.", {
|
|
43648
|
-
engine: exports_external.enum(["playwright", "cdp", "lightpanda", "bun", "auto"]).optional().default("auto"),
|
|
43810
|
+
engine: exports_external.enum(["playwright", "cdp", "lightpanda", "bun", "tui", "auto"]).optional().default("auto"),
|
|
43649
43811
|
use_case: exports_external.string().optional(),
|
|
43650
43812
|
project_id: exports_external.string().optional(),
|
|
43651
43813
|
agent_id: exports_external.string().optional(),
|
|
@@ -45160,7 +45322,7 @@ function register5(server) {
|
|
|
45160
45322
|
max_pages: exports_external.number().optional().default(50),
|
|
45161
45323
|
same_domain: exports_external.boolean().optional().default(true),
|
|
45162
45324
|
project_id: exports_external.string().optional(),
|
|
45163
|
-
engine: exports_external.enum(["playwright", "cdp", "lightpanda", "bun", "auto"]).optional().default("auto")
|
|
45325
|
+
engine: exports_external.enum(["playwright", "cdp", "lightpanda", "bun", "tui", "auto"]).optional().default("auto")
|
|
45164
45326
|
}, async ({ url, max_depth, max_pages, same_domain, project_id, engine }) => {
|
|
45165
45327
|
try {
|
|
45166
45328
|
const result = await crawl(url, {
|
|
@@ -45242,7 +45404,7 @@ function register6(server) {
|
|
|
45242
45404
|
server.tool("browser_script_run", "Run a saved script asynchronously. Returns run_id immediately \u2014 poll with browser_script_status for step-by-step progress. Scripts combine browser actions + connector calls + AI reasoning. Works with any engine (Bun.WebView, Playwright, CDP).", {
|
|
45243
45405
|
name: exports_external.string().describe("Script name"),
|
|
45244
45406
|
session_id: exports_external.string().optional(),
|
|
45245
|
-
engine: exports_external.enum(["playwright", "cdp", "lightpanda", "bun", "auto"]).optional().default("auto"),
|
|
45407
|
+
engine: exports_external.enum(["playwright", "cdp", "lightpanda", "bun", "tui", "auto"]).optional().default("auto"),
|
|
45246
45408
|
variables: exports_external.record(exports_external.string()).optional().describe("Override script variables")
|
|
45247
45409
|
}, async ({ name, session_id, engine, variables }) => {
|
|
45248
45410
|
try {
|