unbrowse 6.5.2 → 6.6.0-preview.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.js +17 -2
- package/dist/mcp.js +4 -4
- package/dist/server.js +255 -6
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -31,7 +31,7 @@ var __promiseAll = (args) => Promise.all(args);
|
|
|
31
31
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
32
32
|
|
|
33
33
|
// ../../src/build-info.generated.ts
|
|
34
|
-
var BUILD_RELEASE_VERSION = "6.
|
|
34
|
+
var BUILD_RELEASE_VERSION = "6.6.0-preview.0", BUILD_GIT_SHA = "e74cd1481aa5", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiNi42LjAtcHJldmlldy4wIiwiZ2l0X3NoYSI6ImU3NGNkMTQ4MWFhNSIsImNvZGVfaGFzaCI6IjVkOWViZjYxOWM2MSIsInRyYWNlX3ZlcnNpb24iOiI1ZDllYmY2MTljNjFAZTc0Y2QxNDgxYWE1IiwiaXNzdWVkX2F0IjoiMjAyNi0wNS0wNFQwNTo1MTo1Mi4yNTNaIn0", BUILD_RELEASE_MANIFEST_SIGNATURE = "_hrkIsHrYUpg_q-N3P2xraayyLNVbgdyB8-8cRupt6U", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai", BUILD_DEFAULT_PROFILE = "";
|
|
35
35
|
|
|
36
36
|
// ../../src/version.ts
|
|
37
37
|
import { createHash } from "crypto";
|
|
@@ -6609,10 +6609,25 @@ function printHelp() {
|
|
|
6609
6609
|
async function cmdStatus(flags) {
|
|
6610
6610
|
const healthy = await fetch(`${BASE_URL}/health`, { signal: AbortSignal.timeout(2000) }).then((r) => r.ok).catch(() => false);
|
|
6611
6611
|
const versionInfo = checkServerVersion(BASE_URL, import.meta.url);
|
|
6612
|
+
let activeSessions = [];
|
|
6613
|
+
let sessionCount = 0;
|
|
6614
|
+
if (healthy) {
|
|
6615
|
+
try {
|
|
6616
|
+
const res = await fetch(`${BASE_URL}/v1/browse/sessions`, { signal: AbortSignal.timeout(2000) });
|
|
6617
|
+
if (res.ok) {
|
|
6618
|
+
const data = await res.json();
|
|
6619
|
+
activeSessions = data.sessions ?? [];
|
|
6620
|
+
sessionCount = data.count ?? activeSessions.length;
|
|
6621
|
+
}
|
|
6622
|
+
} catch {}
|
|
6623
|
+
}
|
|
6612
6624
|
output({
|
|
6613
6625
|
server: healthy ? "running" : "stopped",
|
|
6614
6626
|
url: BASE_URL,
|
|
6615
|
-
...versionInfo ?? {}
|
|
6627
|
+
...versionInfo ?? {},
|
|
6628
|
+
active_browse_sessions: sessionCount,
|
|
6629
|
+
sessions: activeSessions,
|
|
6630
|
+
chrome_debug_url: process.env.CHROME_DEBUG_URL ?? null
|
|
6616
6631
|
}, !!flags.pretty);
|
|
6617
6632
|
}
|
|
6618
6633
|
async function cmdRestart(flags) {
|
package/dist/mcp.js
CHANGED
|
@@ -226,11 +226,11 @@ import { dirname, join, parse } from "path";
|
|
|
226
226
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
227
227
|
|
|
228
228
|
// ../../src/build-info.generated.ts
|
|
229
|
-
var BUILD_RELEASE_VERSION = "6.
|
|
230
|
-
var BUILD_GIT_SHA = "
|
|
229
|
+
var BUILD_RELEASE_VERSION = "6.6.0-preview.0";
|
|
230
|
+
var BUILD_GIT_SHA = "e74cd1481aa5";
|
|
231
231
|
var BUILD_CODE_HASH = "5d9ebf619c61";
|
|
232
|
-
var BUILD_RELEASE_MANIFEST_BASE64 = "
|
|
233
|
-
var BUILD_RELEASE_MANIFEST_SIGNATURE = "
|
|
232
|
+
var BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiNi42LjAtcHJldmlldy4wIiwiZ2l0X3NoYSI6ImU3NGNkMTQ4MWFhNSIsImNvZGVfaGFzaCI6IjVkOWViZjYxOWM2MSIsInRyYWNlX3ZlcnNpb24iOiI1ZDllYmY2MTljNjFAZTc0Y2QxNDgxYWE1IiwiaXNzdWVkX2F0IjoiMjAyNi0wNS0wNFQwNTo1MTo1Mi4yNTNaIn0";
|
|
233
|
+
var BUILD_RELEASE_MANIFEST_SIGNATURE = "_hrkIsHrYUpg_q-N3P2xraayyLNVbgdyB8-8cRupt6U";
|
|
234
234
|
var BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
|
|
235
235
|
var BUILD_DEFAULT_PROFILE = "";
|
|
236
236
|
|
package/dist/server.js
CHANGED
|
@@ -211,13 +211,11 @@ function resolveKuriLaunchConfig(env = process.env) {
|
|
|
211
211
|
headless = true;
|
|
212
212
|
}
|
|
213
213
|
const cleanRoom = envFlag(env.UNBROWSE_LOCAL_ONLY) || envFlag(env.KURI_CLEAN_ROOM);
|
|
214
|
-
const browserCookieOptOut = falseyEnv(env.UNBROWSE_IMPORT_BROWSER_COOKIES);
|
|
215
|
-
const explicitAttach = envFlag(env.KURI_ATTACH_EXISTING_CHROME ?? env.UNBROWSE_ATTACH_EXISTING_CHROME);
|
|
216
214
|
const disableCdpAttach = envFlag(env.KURI_DISABLE_CDP_ATTACH);
|
|
217
|
-
const
|
|
215
|
+
const attachToExistingChrome = !disableCdpAttach && !cleanRoom;
|
|
218
216
|
return {
|
|
219
217
|
headless,
|
|
220
|
-
attachToExistingChrome
|
|
218
|
+
attachToExistingChrome
|
|
221
219
|
};
|
|
222
220
|
}
|
|
223
221
|
function kuriBinaryName() {
|
|
@@ -7344,7 +7342,7 @@ var init_capture = __esm(async () => {
|
|
|
7344
7342
|
});
|
|
7345
7343
|
|
|
7346
7344
|
// ../../src/build-info.generated.ts
|
|
7347
|
-
var BUILD_RELEASE_VERSION = "6.
|
|
7345
|
+
var BUILD_RELEASE_VERSION = "6.6.0-preview.0", BUILD_GIT_SHA = "e74cd1481aa5", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiNi42LjAtcHJldmlldy4wIiwiZ2l0X3NoYSI6ImU3NGNkMTQ4MWFhNSIsImNvZGVfaGFzaCI6IjVkOWViZjYxOWM2MSIsInRyYWNlX3ZlcnNpb24iOiI1ZDllYmY2MTljNjFAZTc0Y2QxNDgxYWE1IiwiaXNzdWVkX2F0IjoiMjAyNi0wNS0wNFQwNTo1MTo1Mi4yNTNaIn0", BUILD_RELEASE_MANIFEST_SIGNATURE = "_hrkIsHrYUpg_q-N3P2xraayyLNVbgdyB8-8cRupt6U", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai", BUILD_DEFAULT_PROFILE = "";
|
|
7348
7346
|
|
|
7349
7347
|
// ../../src/version.ts
|
|
7350
7348
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -28155,6 +28153,74 @@ async function registerRoutes(app) {
|
|
|
28155
28153
|
next_step: settings.auto_publish_checkpoints ? "Auto-publish after sync/close is enabled unless a domain rule blocks it." : "Auto-publish after sync/close is disabled. Use index for local recompute and publish only when you explicitly want remote share."
|
|
28156
28154
|
});
|
|
28157
28155
|
});
|
|
28156
|
+
app.get("/v1/browse/sessions", async (_req, reply) => {
|
|
28157
|
+
const sessions = Array.from(browseSessions.values()).map((s) => ({
|
|
28158
|
+
session_id: s.sessionId,
|
|
28159
|
+
tab_id: s.tabId,
|
|
28160
|
+
url: s.url,
|
|
28161
|
+
domain: s.domain,
|
|
28162
|
+
har_active: s.harActive,
|
|
28163
|
+
broker_port: s.brokerPort ?? null,
|
|
28164
|
+
streaming_publish_active: streamingWatchers.has(s.sessionId)
|
|
28165
|
+
}));
|
|
28166
|
+
return reply.send({ sessions, count: sessions.length });
|
|
28167
|
+
});
|
|
28168
|
+
app.get("/v1/browse/sessions/:id/buffer", async (req, reply) => {
|
|
28169
|
+
const { id } = req.params;
|
|
28170
|
+
let session;
|
|
28171
|
+
for (const s of browseSessions.values()) {
|
|
28172
|
+
if (s.sessionId === id || s.tabId === id) {
|
|
28173
|
+
session = s;
|
|
28174
|
+
break;
|
|
28175
|
+
}
|
|
28176
|
+
}
|
|
28177
|
+
if (!session)
|
|
28178
|
+
return reply.code(404).send({ error: "session_not_found", id });
|
|
28179
|
+
let intercepted = [];
|
|
28180
|
+
let interceptError = null;
|
|
28181
|
+
try {
|
|
28182
|
+
intercepted = await collectInterceptedRequests(session.tabId);
|
|
28183
|
+
} catch (err) {
|
|
28184
|
+
interceptError = err instanceof Error ? err.message : String(err);
|
|
28185
|
+
}
|
|
28186
|
+
let harEntries = [];
|
|
28187
|
+
let harError = null;
|
|
28188
|
+
if (session.harActive) {
|
|
28189
|
+
try {
|
|
28190
|
+
const broker = brokerForSession(session);
|
|
28191
|
+
const stopResult = await broker.harStop(session.tabId);
|
|
28192
|
+
harEntries = stopResult.entries ?? [];
|
|
28193
|
+
try {
|
|
28194
|
+
await broker.harStart(session.tabId);
|
|
28195
|
+
} catch {}
|
|
28196
|
+
} catch (err) {
|
|
28197
|
+
harError = err instanceof Error ? err.message : String(err);
|
|
28198
|
+
}
|
|
28199
|
+
}
|
|
28200
|
+
return reply.send({
|
|
28201
|
+
session: {
|
|
28202
|
+
session_id: session.sessionId,
|
|
28203
|
+
tab_id: session.tabId,
|
|
28204
|
+
url: session.url,
|
|
28205
|
+
domain: session.domain,
|
|
28206
|
+
har_active: session.harActive,
|
|
28207
|
+
streaming_publish_active: streamingWatchers.has(session.sessionId)
|
|
28208
|
+
},
|
|
28209
|
+
intercepted_requests: intercepted,
|
|
28210
|
+
intercepted_count: Array.isArray(intercepted) ? intercepted.length : 0,
|
|
28211
|
+
intercept_error: interceptError,
|
|
28212
|
+
har_entries: harEntries.map((e) => ({
|
|
28213
|
+
url: e?.request?.url,
|
|
28214
|
+
method: e?.request?.method,
|
|
28215
|
+
status: e?.response?.status,
|
|
28216
|
+
mime_type: e?.response?.content?.mimeType,
|
|
28217
|
+
size: e?.response?.bodySize
|
|
28218
|
+
})),
|
|
28219
|
+
har_count: harEntries.length,
|
|
28220
|
+
har_error: harError,
|
|
28221
|
+
total_captured: (Array.isArray(intercepted) ? intercepted.length : 0) + harEntries.length
|
|
28222
|
+
});
|
|
28223
|
+
});
|
|
28158
28224
|
app.get("/v1/trace/:trace_id", async (req, reply) => {
|
|
28159
28225
|
const { trace_id } = req.params;
|
|
28160
28226
|
const traceDir = path6.join(process.env.UNBROWSE_TRACE_DIR ?? path6.join(os4.homedir(), ".unbrowse", "traces"));
|
|
@@ -28181,6 +28247,25 @@ async function registerRoutes(app) {
|
|
|
28181
28247
|
const { intent, params, context, projection, confirm_unsafe, confirm_third_party_terms, dry_run, force_capture, skip_robots_check, visual_context, budget_ms } = req.body;
|
|
28182
28248
|
if (!intent)
|
|
28183
28249
|
return reply.code(400).send({ error: "intent required" });
|
|
28250
|
+
let inflightFlushResult = null;
|
|
28251
|
+
if (context?.url && !force_capture) {
|
|
28252
|
+
try {
|
|
28253
|
+
const activeSession = findActiveSessionForDomain(context.url);
|
|
28254
|
+
if (activeSession) {
|
|
28255
|
+
const flushed = await lightFlushBrowseCapture(activeSession);
|
|
28256
|
+
if (flushed.request_count > 0) {
|
|
28257
|
+
inflightFlushResult = {
|
|
28258
|
+
skill_id: flushed.skill_id,
|
|
28259
|
+
request_count: flushed.request_count,
|
|
28260
|
+
endpoint_count: flushed.endpoint_count
|
|
28261
|
+
};
|
|
28262
|
+
console.log(`[in-flight-flush] session=${activeSession.sessionId.slice(0, 8)} domain=${flushed.domain} requests=${flushed.request_count} endpoints=${flushed.endpoint_count} skill=${flushed.skill_id?.slice(0, 15) ?? "none"}`);
|
|
28263
|
+
}
|
|
28264
|
+
}
|
|
28265
|
+
} catch (err) {
|
|
28266
|
+
console.warn(`[in-flight-flush] failed: ${err.message}`);
|
|
28267
|
+
}
|
|
28268
|
+
}
|
|
28184
28269
|
try {
|
|
28185
28270
|
const result = await resolveAndExecute(intent, params ?? {}, context, projection, { confirm_unsafe, confirm_third_party_terms, dry_run, force_capture, skip_robots_check, client_scope: clientScope, budget_ms });
|
|
28186
28271
|
const res = attachAgentOutcomeHints({ ...result }, {
|
|
@@ -28209,6 +28294,9 @@ async function registerRoutes(app) {
|
|
|
28209
28294
|
}
|
|
28210
28295
|
} catch {}
|
|
28211
28296
|
}
|
|
28297
|
+
if (inflightFlushResult) {
|
|
28298
|
+
res.inflight_flush = inflightFlushResult;
|
|
28299
|
+
}
|
|
28212
28300
|
return reply.send(res);
|
|
28213
28301
|
} catch (err) {
|
|
28214
28302
|
return reply.code(500).send({ error: err.message });
|
|
@@ -28853,6 +28941,141 @@ async function registerRoutes(app) {
|
|
|
28853
28941
|
session.harActive = true;
|
|
28854
28942
|
await injectInterceptor(session.tabId).catch(() => {});
|
|
28855
28943
|
}
|
|
28944
|
+
async function lightFlushBrowseCapture(session) {
|
|
28945
|
+
let harEntries = [];
|
|
28946
|
+
if (session.harActive) {
|
|
28947
|
+
try {
|
|
28948
|
+
const broker = brokerForSession(session);
|
|
28949
|
+
const stopResult = await broker.harStop(session.tabId);
|
|
28950
|
+
harEntries = stopResult.entries ?? [];
|
|
28951
|
+
try {
|
|
28952
|
+
await broker.harStart(session.tabId);
|
|
28953
|
+
} catch {}
|
|
28954
|
+
} catch {}
|
|
28955
|
+
}
|
|
28956
|
+
const allRequests = await enrichPassiveCaptureRequests({
|
|
28957
|
+
tabId: session.tabId,
|
|
28958
|
+
captureUrl: session.url,
|
|
28959
|
+
harEntries,
|
|
28960
|
+
intent: `browse ${session.domain || profileName(session.url)}`
|
|
28961
|
+
});
|
|
28962
|
+
if (allRequests.length === 0) {
|
|
28963
|
+
return { skill_id: null, domain: session.domain, request_count: 0, endpoint_count: 0 };
|
|
28964
|
+
}
|
|
28965
|
+
const jsBundles = new Map;
|
|
28966
|
+
try {
|
|
28967
|
+
const intercepted = await collectInterceptedRequests(session.tabId).catch(() => []);
|
|
28968
|
+
for (const entry of intercepted) {
|
|
28969
|
+
if (entry.is_js && entry.response_body && jsBundles.size < 20) {
|
|
28970
|
+
jsBundles.set(entry.url, entry.response_body);
|
|
28971
|
+
}
|
|
28972
|
+
}
|
|
28973
|
+
} catch {}
|
|
28974
|
+
const syncResult = await cacheBrowseRequests({
|
|
28975
|
+
sessionUrl: session.url,
|
|
28976
|
+
sessionDomain: session.domain,
|
|
28977
|
+
requests: allRequests,
|
|
28978
|
+
getPageHtml: () => brokerForSession(session).getPageHtml(session.tabId),
|
|
28979
|
+
jsBundles: jsBundles.size > 0 ? jsBundles : undefined,
|
|
28980
|
+
intent: `browse ${session.domain || profileName(session.url)}`
|
|
28981
|
+
});
|
|
28982
|
+
if (syncResult.skill && syncResult.domain) {
|
|
28983
|
+
const domainKey = getDomainReuseKey(session.url || syncResult.domain);
|
|
28984
|
+
if (domainKey) {
|
|
28985
|
+
const cacheKey2 = scopedCacheKey("local", `${domainKey}:${syncResult.skill.skill_id}`);
|
|
28986
|
+
writeSkillSnapshot(cacheKey2, syncResult.skill);
|
|
28987
|
+
domainSkillCache.set(domainKey, {
|
|
28988
|
+
skillId: syncResult.skill.skill_id,
|
|
28989
|
+
localSkillPath: snapshotPathForCacheKey(cacheKey2),
|
|
28990
|
+
ts: Date.now()
|
|
28991
|
+
});
|
|
28992
|
+
persistDomainCache();
|
|
28993
|
+
}
|
|
28994
|
+
}
|
|
28995
|
+
return {
|
|
28996
|
+
skill_id: syncResult.skill?.skill_id ?? null,
|
|
28997
|
+
domain: syncResult.domain,
|
|
28998
|
+
request_count: allRequests.length,
|
|
28999
|
+
endpoint_count: syncResult.skill?.endpoints.length ?? 0
|
|
29000
|
+
};
|
|
29001
|
+
}
|
|
29002
|
+
function findActiveSessionForDomain(targetUrl) {
|
|
29003
|
+
const targetDomain = getDomainReuseKey(targetUrl);
|
|
29004
|
+
if (!targetDomain)
|
|
29005
|
+
return null;
|
|
29006
|
+
let match = null;
|
|
29007
|
+
for (const session of browseSessions.values()) {
|
|
29008
|
+
if (!session.harActive)
|
|
29009
|
+
continue;
|
|
29010
|
+
const sessionDomain = getDomainReuseKey(session.url);
|
|
29011
|
+
if (sessionDomain === targetDomain)
|
|
29012
|
+
match = session;
|
|
29013
|
+
}
|
|
29014
|
+
return match;
|
|
29015
|
+
}
|
|
29016
|
+
const streamingWatchers = new Map;
|
|
29017
|
+
const STREAMING_INTERVAL_MS = parseInt(process.env.UNBROWSE_STREAMING_INTERVAL_MS ?? "10000", 10);
|
|
29018
|
+
const STREAMING_ENABLED = process.env.UNBROWSE_STREAMING_PUBLISH !== "0";
|
|
29019
|
+
const streamingState = new Map;
|
|
29020
|
+
function startStreamingWatcher(session) {
|
|
29021
|
+
if (!STREAMING_ENABLED)
|
|
29022
|
+
return;
|
|
29023
|
+
if (streamingWatchers.has(session.sessionId))
|
|
29024
|
+
return;
|
|
29025
|
+
streamingState.set(session.sessionId, { lastEndpointCount: 0, lastSkillId: null });
|
|
29026
|
+
const tick = async () => {
|
|
29027
|
+
if (!browseSessions.has(session.sessionId)) {
|
|
29028
|
+
stopStreamingWatcher(session.sessionId);
|
|
29029
|
+
return;
|
|
29030
|
+
}
|
|
29031
|
+
const live = browseSessions.get(session.sessionId);
|
|
29032
|
+
if (!live || !live.harActive)
|
|
29033
|
+
return;
|
|
29034
|
+
try {
|
|
29035
|
+
const flushed = await lightFlushBrowseCapture(live);
|
|
29036
|
+
const state = streamingState.get(session.sessionId);
|
|
29037
|
+
if (!state)
|
|
29038
|
+
return;
|
|
29039
|
+
const grew = flushed.endpoint_count > state.lastEndpointCount || flushed.skill_id && flushed.skill_id !== state.lastSkillId;
|
|
29040
|
+
if (grew && flushed.skill_id) {
|
|
29041
|
+
state.lastEndpointCount = flushed.endpoint_count;
|
|
29042
|
+
state.lastSkillId = flushed.skill_id;
|
|
29043
|
+
const domainKey = getDomainReuseKey(live.url || flushed.domain);
|
|
29044
|
+
const cacheEntry = domainKey ? domainSkillCache.get(domainKey) : null;
|
|
29045
|
+
if (cacheEntry?.localSkillPath) {
|
|
29046
|
+
const skill = readSkillSnapshot(cacheEntry.localSkillPath);
|
|
29047
|
+
if (skill) {
|
|
29048
|
+
const decision = decideCheckpointPublish(flushed.domain);
|
|
29049
|
+
queueBackgroundIndex({
|
|
29050
|
+
skill: { ...skill },
|
|
29051
|
+
domain: flushed.domain,
|
|
29052
|
+
intent: skill.intent_signature || `browse ${flushed.domain}`,
|
|
29053
|
+
contextUrl: live.url,
|
|
29054
|
+
cacheKey: `streaming:${flushed.domain}:${Date.now()}`,
|
|
29055
|
+
publishAfterIndex: decision.publishQueued
|
|
29056
|
+
});
|
|
29057
|
+
console.log(`[streaming-publish] session=${session.sessionId.slice(0, 8)} domain=${flushed.domain} endpoints=${flushed.endpoint_count} publish=${decision.publishQueued}`);
|
|
29058
|
+
}
|
|
29059
|
+
}
|
|
29060
|
+
}
|
|
29061
|
+
} catch (err) {
|
|
29062
|
+
console.warn(`[streaming-publish] tick failed: ${err.message}`);
|
|
29063
|
+
}
|
|
29064
|
+
};
|
|
29065
|
+
const timer = setInterval(() => {
|
|
29066
|
+
tick();
|
|
29067
|
+
}, STREAMING_INTERVAL_MS);
|
|
29068
|
+
streamingWatchers.set(session.sessionId, timer);
|
|
29069
|
+
console.log(`[streaming-publish] watcher started session=${session.sessionId.slice(0, 8)} interval=${STREAMING_INTERVAL_MS}ms`);
|
|
29070
|
+
}
|
|
29071
|
+
function stopStreamingWatcher(sessionId) {
|
|
29072
|
+
const timer = streamingWatchers.get(sessionId);
|
|
29073
|
+
if (timer) {
|
|
29074
|
+
clearInterval(timer);
|
|
29075
|
+
streamingWatchers.delete(sessionId);
|
|
29076
|
+
}
|
|
29077
|
+
streamingState.delete(sessionId);
|
|
29078
|
+
}
|
|
28856
29079
|
async function flushBrowseCapture(session, options = {}) {
|
|
28857
29080
|
let harEntries = [];
|
|
28858
29081
|
if (session.harActive) {
|
|
@@ -29061,6 +29284,7 @@ async function registerRoutes(app) {
|
|
|
29061
29284
|
}
|
|
29062
29285
|
}
|
|
29063
29286
|
} catch {}
|
|
29287
|
+
startStreamingWatcher(session);
|
|
29064
29288
|
return reply.send({
|
|
29065
29289
|
ok: true,
|
|
29066
29290
|
session_id: session.sessionId,
|
|
@@ -29068,7 +29292,20 @@ async function registerRoutes(app) {
|
|
|
29068
29292
|
tab_id: session.tabId,
|
|
29069
29293
|
auth_profile: session.domain,
|
|
29070
29294
|
...result.cookiesInjected > 0 ? { cookies_injected: result.cookiesInjected } : {},
|
|
29071
|
-
...authRequired ? { auth_required: true, auth_hint: authHint } : {}
|
|
29295
|
+
...authRequired ? { auth_required: true, auth_hint: authHint } : {},
|
|
29296
|
+
autonomy: (() => {
|
|
29297
|
+
const publishDecision = decideCheckpointPublish(session.domain);
|
|
29298
|
+
return {
|
|
29299
|
+
har_active: session.harActive,
|
|
29300
|
+
streaming_publish_active: streamingWatchers.has(session.sessionId),
|
|
29301
|
+
attached_existing_chrome: result.attachedExistingChrome ?? false,
|
|
29302
|
+
chrome_debug_url: process.env.CHROME_DEBUG_URL ?? null,
|
|
29303
|
+
inspect_buffer: `GET ${process.env.UNBROWSE_API_BASE ?? "http://127.0.0.1:6969"}/v1/browse/sessions/${session.sessionId}/buffer`,
|
|
29304
|
+
marketplace_publish_enabled: publishDecision.publishQueued,
|
|
29305
|
+
marketplace_publish_mode: publishDecision.mode,
|
|
29306
|
+
marketplace_publish_reason: publishDecision.reason
|
|
29307
|
+
};
|
|
29308
|
+
})()
|
|
29072
29309
|
});
|
|
29073
29310
|
} catch (error) {
|
|
29074
29311
|
return sendBrowseSessionError(reply, error);
|
|
@@ -29110,6 +29347,7 @@ async function registerRoutes(app) {
|
|
|
29110
29347
|
activeSession.domain = profileName(activeSession.url);
|
|
29111
29348
|
const stillLive = await isBrowseSessionLive(activeSession, browseClient).catch(() => false);
|
|
29112
29349
|
if (!stillLive) {
|
|
29350
|
+
stopStreamingWatcher(activeSession.sessionId);
|
|
29113
29351
|
removeBrowseSession(browseSessions, activeSession.sessionId);
|
|
29114
29352
|
throw new BrowseSessionError("session_expired");
|
|
29115
29353
|
}
|
|
@@ -29337,6 +29575,7 @@ async function registerRoutes(app) {
|
|
|
29337
29575
|
await saveAuthProfileBestEffort(session2.tabId, session2.domain, "browse_close");
|
|
29338
29576
|
}
|
|
29339
29577
|
const syncResult2 = await flushBrowseCapture(session2, { queueIndex: true, queuePublish: true });
|
|
29578
|
+
stopStreamingWatcher(session2.sessionId);
|
|
29340
29579
|
await broker.closeTab(session2.tabId).catch(() => {});
|
|
29341
29580
|
removeBrowseSession(browseSessions, session2.sessionId);
|
|
29342
29581
|
return syncResult2;
|
|
@@ -29459,6 +29698,16 @@ async function startUnbrowseServer(options = {}) {
|
|
|
29459
29698
|
process.env.UNBROWSE_SKIP_TOS_CHECK = "1";
|
|
29460
29699
|
}
|
|
29461
29700
|
startBackgroundRegistration();
|
|
29701
|
+
const UNBROWSE_CDP_PORT = Number(process.env.UNBROWSE_CDP_PORT ?? 9222);
|
|
29702
|
+
if (!process.env.CHROME_DEBUG_URL) {
|
|
29703
|
+
process.env.CHROME_DEBUG_URL = `http://127.0.0.1:${UNBROWSE_CDP_PORT}`;
|
|
29704
|
+
}
|
|
29705
|
+
if (!process.env.PUPPETEER_BROWSER_WS_ENDPOINT) {
|
|
29706
|
+
process.env.PUPPETEER_BROWSER_WS_ENDPOINT = `ws://127.0.0.1:${UNBROWSE_CDP_PORT}`;
|
|
29707
|
+
}
|
|
29708
|
+
if (!process.env.PLAYWRIGHT_CHROMIUM_REMOTE_DEBUGGING_URL) {
|
|
29709
|
+
process.env.PLAYWRIGHT_CHROMIUM_REMOTE_DEBUGGING_URL = `http://127.0.0.1:${UNBROWSE_CDP_PORT}`;
|
|
29710
|
+
}
|
|
29462
29711
|
const app = Fastify({ logger: options.logger ?? true });
|
|
29463
29712
|
await app.register(cors, { origin: true });
|
|
29464
29713
|
await registerRateLimiter(app);
|