unbrowse 9.4.12 → 9.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unbrowse",
3
- "version": "9.4.12",
3
+ "version": "9.5.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/unbrowse-ai/unbrowse.git"
package/runtime/cli.js CHANGED
@@ -2223,7 +2223,7 @@ var init_telemetry = __esm(() => {
2223
2223
  });
2224
2224
 
2225
2225
  // .tmp-runtime-src/build-info.generated.ts
2226
- var BUILD_RELEASE_VERSION = "9.4.12", BUILD_GIT_SHA = "6bd7d5a576a9", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiOS40LjEyIiwiZ2l0X3NoYSI6IjZiZDdkNWE1NzZhOSIsImNvZGVfaGFzaCI6IjVkOWViZjYxOWM2MSIsInRyYWNlX3ZlcnNpb24iOiI1ZDllYmY2MTljNjFANmJkN2Q1YTU3NmE5IiwiaXNzdWVkX2F0IjoiMjAyNi0wNi0xN1QxMTowMzoxMy4yNjRaIn0", BUILD_RELEASE_MANIFEST_SIGNATURE = "zuZ8t79ntQFNKMX1N1W22R9drkrj9_VjWOUwIIJ5Q64", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai", BUILD_DEFAULT_PROFILE = "";
2226
+ var BUILD_RELEASE_VERSION = "9.5.0", BUILD_GIT_SHA = "e89197aa72c5", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiOS41LjAiLCJnaXRfc2hhIjoiZTg5MTk3YWE3MmM1IiwiY29kZV9oYXNoIjoiNWQ5ZWJmNjE5YzYxIiwidHJhY2VfdmVyc2lvbiI6IjVkOWViZjYxOWM2MUBlODkxOTdhYTcyYzUiLCJpc3N1ZWRfYXQiOiIyMDI2LTA2LTE3VDIwOjQzOjE0LjU3NVoifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "1UkHiCAP05Uq70_rXEXyo_0Z_VqVHG23WPNTxBlX5Fo", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai", BUILD_DEFAULT_PROFILE = "";
2227
2227
 
2228
2228
  // .tmp-runtime-src/version.ts
2229
2229
  import { createHash as createHash7 } from "crypto";
@@ -8292,7 +8292,8 @@ async function recordAnalyticsSession(payload) {
8292
8292
  return;
8293
8293
  await api("POST", "/v1/analytics/sessions", {
8294
8294
  ...getTelemetryAttribution(),
8295
- ...payload
8295
+ ...payload,
8296
+ install_id: getInstallId()
8296
8297
  });
8297
8298
  }
8298
8299
  async function recordRoutingTelemetry(events) {
@@ -123596,6 +123597,125 @@ var init_fetch_ladder = __esm(() => {
123596
123597
  ];
123597
123598
  });
123598
123599
 
123600
+ // .tmp-runtime-src/execution/tencent-waf-solve.ts
123601
+ function parseCapzyProxy(proxyUrl) {
123602
+ try {
123603
+ const u = new URL(proxyUrl);
123604
+ if (!u.hostname || !u.port)
123605
+ return;
123606
+ const scheme = u.protocol.replace(":", "").toLowerCase();
123607
+ const type = scheme === "socks5" || scheme === "socks4" || scheme === "https" ? scheme : "http";
123608
+ return {
123609
+ type,
123610
+ address: u.hostname,
123611
+ port: Number(u.port),
123612
+ ...u.username ? { login: decodeURIComponent(u.username) } : {},
123613
+ ...u.password ? { password: decodeURIComponent(u.password) } : {}
123614
+ };
123615
+ } catch {
123616
+ return;
123617
+ }
123618
+ }
123619
+
123620
+ // .tmp-runtime-src/execution/capzy-cf-solve.ts
123621
+ function extractCfClearance(solution) {
123622
+ if (!solution || typeof solution !== "object")
123623
+ return null;
123624
+ const s = solution;
123625
+ const ua = typeof s.user_agent === "string" && s.user_agent || typeof s.userAgent === "string" && s.userAgent || undefined;
123626
+ if (typeof s.cf_clearance === "string" && s.cf_clearance) {
123627
+ return { cf_clearance: s.cf_clearance, user_agent: ua || undefined };
123628
+ }
123629
+ if (typeof s.token === "string" && s.token && s.type !== "turnstile") {
123630
+ return { cf_clearance: s.token, user_agent: ua || undefined };
123631
+ }
123632
+ const cookies = s.cookies;
123633
+ if (cookies && typeof cookies === "object" && !Array.isArray(cookies)) {
123634
+ const v = cookies.cf_clearance;
123635
+ if (typeof v === "string" && v)
123636
+ return { cf_clearance: v, user_agent: ua || undefined };
123637
+ }
123638
+ if (Array.isArray(cookies)) {
123639
+ for (const c of cookies) {
123640
+ if (c && typeof c === "object") {
123641
+ const o = c;
123642
+ if (o.name === "cf_clearance" && typeof o.value === "string" && o.value) {
123643
+ return { cf_clearance: o.value, user_agent: ua || undefined };
123644
+ }
123645
+ } else if (typeof c === "string" && c.startsWith("cf_clearance=")) {
123646
+ const v = c.slice("cf_clearance=".length).split(";")[0];
123647
+ if (v)
123648
+ return { cf_clearance: v, user_agent: ua || undefined };
123649
+ }
123650
+ }
123651
+ }
123652
+ return null;
123653
+ }
123654
+ function buildCfTask(websiteURL, proxy) {
123655
+ return {
123656
+ type: "AntiCloudflareTask",
123657
+ websiteURL,
123658
+ proxyType: proxy.type,
123659
+ proxyAddress: proxy.address,
123660
+ proxyPort: proxy.port,
123661
+ ...proxy.login ? { proxyLogin: proxy.login } : {},
123662
+ ...proxy.password ? { proxyPassword: proxy.password } : {}
123663
+ };
123664
+ }
123665
+ async function solveCfViaCapzy(input) {
123666
+ const clientKey = input.clientKey ?? process.env.UNBROWSE_CAPZY_KEY?.trim();
123667
+ if (!clientKey)
123668
+ return null;
123669
+ if (!input.proxy)
123670
+ return null;
123671
+ const apiBase = (input.apiBase ?? process.env.UNBROWSE_CAPZY_URL?.trim() ?? "https://api.capzy.ai").replace(/\/+$/, "");
123672
+ const doFetch = input.fetchImpl ?? fetch;
123673
+ const deadline = Date.now() + (input.timeoutMs ?? 120000);
123674
+ const task = buildCfTask(input.websiteURL, input.proxy);
123675
+ let taskId;
123676
+ try {
123677
+ const created = await doFetch(`${apiBase}/createTask`, {
123678
+ method: "POST",
123679
+ headers: { "Content-Type": "application/json" },
123680
+ body: JSON.stringify({ clientKey, task }),
123681
+ signal: AbortSignal.timeout(Math.max(1, Math.min(20000, deadline - Date.now())))
123682
+ });
123683
+ if (!created.ok)
123684
+ return null;
123685
+ const cj = await created.json().catch(() => null);
123686
+ if (!cj || cj.errorId || !cj.taskId)
123687
+ return null;
123688
+ taskId = cj.taskId;
123689
+ } catch {
123690
+ return null;
123691
+ }
123692
+ while (Date.now() < deadline) {
123693
+ try {
123694
+ const res = await doFetch(`${apiBase}/getTaskResult`, {
123695
+ method: "POST",
123696
+ headers: { "Content-Type": "application/json" },
123697
+ body: JSON.stringify({ clientKey, taskId }),
123698
+ signal: AbortSignal.timeout(Math.max(1, Math.min(15000, deadline - Date.now())))
123699
+ });
123700
+ if (!res.ok)
123701
+ return null;
123702
+ const rj = await res.json().catch(() => null);
123703
+ if (!rj || rj.errorId)
123704
+ return null;
123705
+ if (rj.status === "failed")
123706
+ return null;
123707
+ if (rj.status === "ready") {
123708
+ return extractCfClearance(rj.solution);
123709
+ }
123710
+ } catch {
123711
+ return null;
123712
+ }
123713
+ await new Promise((r) => setTimeout(r, 2500));
123714
+ }
123715
+ return null;
123716
+ }
123717
+ var init_capzy_cf_solve = () => {};
123718
+
123599
123719
  // .tmp-runtime-src/execution/cf-challenge.ts
123600
123720
  var exports_cf_challenge = {};
123601
123721
  __export(exports_cf_challenge, {
@@ -123616,6 +123736,31 @@ function extractCfBundleUrl(body, requestUrl) {
123616
123736
  }
123617
123737
  }
123618
123738
  async function solveCfAndRetry(input) {
123739
+ if (process.env.UNBROWSE_CAPZY_KEY?.trim()) {
123740
+ const viaCapzy = await solveCfViaCapzy({
123741
+ websiteURL: input.url,
123742
+ proxy: input.proxy ? parseCapzyProxy(input.proxy) : undefined,
123743
+ timeoutMs: input.timeoutMs
123744
+ });
123745
+ if (viaCapzy?.cf_clearance) {
123746
+ const merged2 = mergeCookieJar(input.cookies ?? [], [
123747
+ { name: "cf_clearance", value: viaCapzy.cf_clearance }
123748
+ ]);
123749
+ const cookieHeader2 = merged2.map((c) => `${c.name}=${c.value}`).join("; ");
123750
+ try {
123751
+ const retry = await globalThis.fetch(input.url, {
123752
+ method: "GET",
123753
+ headers: {
123754
+ ...cookieHeader2 ? { cookie: cookieHeader2 } : {},
123755
+ ...viaCapzy.user_agent ? { "user-agent": viaCapzy.user_agent } : {}
123756
+ }
123757
+ });
123758
+ if (retry.status >= 200 && retry.status < 400) {
123759
+ return { status: retry.status, html: await retry.text(), cookies: merged2 };
123760
+ }
123761
+ } catch {}
123762
+ }
123763
+ }
123619
123764
  const bundleUrl = extractCfBundleUrl(input.body, input.url);
123620
123765
  if (!bundleUrl)
123621
123766
  return null;
@@ -123697,6 +123842,7 @@ function mergeCookieJar(a, b) {
123697
123842
  var CF_BUNDLE_RE;
123698
123843
  var init_cf_challenge = __esm(() => {
123699
123844
  init_bundle_replay_client();
123845
+ init_capzy_cf_solve();
123700
123846
  CF_BUNDLE_RE = /src=["'](\/cdn-cgi\/challenge-platform\/h\/[gb]\/scripts\/jsd\/[a-f0-9]+\/main\.js)/i;
123701
123847
  });
123702
123848
 
@@ -154010,7 +154156,7 @@ var exports_tencent_waf_solve = {};
154010
154156
  __export(exports_tencent_waf_solve, {
154011
154157
  submitWafClearance: () => submitWafClearance,
154012
154158
  solveTencentViaCapzy: () => solveTencentViaCapzy,
154013
- parseCapzyProxy: () => parseCapzyProxy,
154159
+ parseCapzyProxy: () => parseCapzyProxy2,
154014
154160
  mergeCookieHeader: () => mergeCookieHeader,
154015
154161
  extractTencentChallenge: () => extractTencentChallenge,
154016
154162
  clearTencentWafViaCapzy: () => clearTencentWafViaCapzy
@@ -154111,7 +154257,7 @@ async function submitWafClearance(input) {
154111
154257
  return { ok: false, status: 0, setCookies: [] };
154112
154258
  }
154113
154259
  }
154114
- function parseCapzyProxy(proxyUrl) {
154260
+ function parseCapzyProxy2(proxyUrl) {
154115
154261
  try {
154116
154262
  const u = new URL(proxyUrl);
154117
154263
  if (!u.hostname || !u.port)
@@ -154152,7 +154298,7 @@ async function clearTencentWafViaCapzy(input) {
154152
154298
  websiteURL: input.url,
154153
154299
  appId: challenge.appId,
154154
154300
  clientKey: input.capzyKey,
154155
- proxy: input.proxyUrl ? parseCapzyProxy(input.proxyUrl) : undefined,
154301
+ proxy: input.proxyUrl ? parseCapzyProxy2(input.proxyUrl) : undefined,
154156
154302
  timeoutMs: input.timeoutMs,
154157
154303
  fetchImpl: input.fetchImpl
154158
154304
  });
package/runtime/mcp.js CHANGED
@@ -36310,7 +36310,7 @@ var init_cached_resolution = __esm(() => {
36310
36310
  });
36311
36311
 
36312
36312
  // .tmp-runtime-src/build-info.generated.ts
36313
- var BUILD_RELEASE_VERSION = "9.4.12", BUILD_GIT_SHA = "6bd7d5a576a9", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiOS40LjEyIiwiZ2l0X3NoYSI6IjZiZDdkNWE1NzZhOSIsImNvZGVfaGFzaCI6IjVkOWViZjYxOWM2MSIsInRyYWNlX3ZlcnNpb24iOiI1ZDllYmY2MTljNjFANmJkN2Q1YTU3NmE5IiwiaXNzdWVkX2F0IjoiMjAyNi0wNi0xN1QxMTowMzoxMy4yNjRaIn0", BUILD_RELEASE_MANIFEST_SIGNATURE = "zuZ8t79ntQFNKMX1N1W22R9drkrj9_VjWOUwIIJ5Q64", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai", BUILD_DEFAULT_PROFILE = "";
36313
+ var BUILD_RELEASE_VERSION = "9.5.0", BUILD_GIT_SHA = "e89197aa72c5", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiOS41LjAiLCJnaXRfc2hhIjoiZTg5MTk3YWE3MmM1IiwiY29kZV9oYXNoIjoiNWQ5ZWJmNjE5YzYxIiwidHJhY2VfdmVyc2lvbiI6IjVkOWViZjYxOWM2MUBlODkxOTdhYTcyYzUiLCJpc3N1ZWRfYXQiOiIyMDI2LTA2LTE3VDIwOjQzOjE0LjU3NVoifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "1UkHiCAP05Uq70_rXEXyo_0Z_VqVHG23WPNTxBlX5Fo", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai", BUILD_DEFAULT_PROFILE = "";
36314
36314
 
36315
36315
  // .tmp-runtime-src/version.ts
36316
36316
  import { createHash as createHash4 } from "crypto";
@@ -42792,7 +42792,8 @@ async function recordAnalyticsSession(payload) {
42792
42792
  return;
42793
42793
  await api("POST", "/v1/analytics/sessions", {
42794
42794
  ...getTelemetryAttribution(),
42795
- ...payload
42795
+ ...payload,
42796
+ install_id: getInstallId()
42796
42797
  });
42797
42798
  }
42798
42799
  async function recordRoutingTelemetry(events) {
@@ -121817,6 +121818,292 @@ var init_fetch_ladder = __esm(() => {
121817
121818
  ];
121818
121819
  });
121819
121820
 
121821
+ // .tmp-runtime-src/execution/tencent-waf-solve.ts
121822
+ var exports_tencent_waf_solve = {};
121823
+ __export(exports_tencent_waf_solve, {
121824
+ submitWafClearance: () => submitWafClearance,
121825
+ solveTencentViaCapzy: () => solveTencentViaCapzy,
121826
+ parseCapzyProxy: () => parseCapzyProxy,
121827
+ mergeCookieHeader: () => mergeCookieHeader,
121828
+ extractTencentChallenge: () => extractTencentChallenge,
121829
+ clearTencentWafViaCapzy: () => clearTencentWafViaCapzy
121830
+ });
121831
+ function extractTencentChallenge(html3) {
121832
+ if (!html3 || typeof html3 !== "string")
121833
+ return null;
121834
+ const appMatch = html3.match(/new\s+Captcha\(\s*["']([0-9]{5,})["']/);
121835
+ const seqMatch = html3.match(/var\s+seqid\s*=\s*["']([^"']+?)["']/);
121836
+ if (!appMatch || !seqMatch)
121837
+ return null;
121838
+ return { appId: appMatch[1], seqid: seqMatch[1] };
121839
+ }
121840
+ async function solveTencentViaCapzy(input) {
121841
+ const clientKey = input.clientKey ?? process.env.UNBROWSE_CAPZY_KEY?.trim();
121842
+ if (!clientKey)
121843
+ return null;
121844
+ const apiBase = (input.apiBase ?? process.env.UNBROWSE_CAPZY_URL?.trim() ?? "https://api.capzy.ai").replace(/\/+$/, "");
121845
+ const doFetch = input.fetchImpl ?? fetch;
121846
+ const deadline = Date.now() + (input.timeoutMs ?? 90000);
121847
+ const task = input.proxy ? {
121848
+ type: "TencentTask",
121849
+ websiteURL: input.websiteURL,
121850
+ websiteKey: input.appId,
121851
+ proxyType: input.proxy.type,
121852
+ proxyAddress: input.proxy.address,
121853
+ proxyPort: input.proxy.port,
121854
+ ...input.proxy.login ? { proxyLogin: input.proxy.login } : {},
121855
+ ...input.proxy.password ? { proxyPassword: input.proxy.password } : {}
121856
+ } : {
121857
+ type: "TencentTaskProxyLess",
121858
+ websiteURL: input.websiteURL,
121859
+ websiteKey: input.appId
121860
+ };
121861
+ let taskId;
121862
+ try {
121863
+ const created = await doFetch(`${apiBase}/createTask`, {
121864
+ method: "POST",
121865
+ headers: { "Content-Type": "application/json" },
121866
+ body: JSON.stringify({ clientKey, task }),
121867
+ signal: AbortSignal.timeout(Math.max(1, Math.min(20000, deadline - Date.now())))
121868
+ });
121869
+ if (!created.ok)
121870
+ return null;
121871
+ const cj = await created.json().catch(() => null);
121872
+ if (!cj || cj.errorId || !cj.taskId)
121873
+ return null;
121874
+ taskId = cj.taskId;
121875
+ } catch {
121876
+ return null;
121877
+ }
121878
+ while (Date.now() < deadline) {
121879
+ try {
121880
+ const res = await doFetch(`${apiBase}/getTaskResult`, {
121881
+ method: "POST",
121882
+ headers: { "Content-Type": "application/json" },
121883
+ body: JSON.stringify({ clientKey, taskId }),
121884
+ signal: AbortSignal.timeout(Math.max(1, Math.min(15000, deadline - Date.now())))
121885
+ });
121886
+ if (!res.ok)
121887
+ return null;
121888
+ const rj = await res.json().catch(() => null);
121889
+ if (!rj || rj.errorId)
121890
+ return null;
121891
+ if (rj.status === "ready") {
121892
+ const s = rj.solution ?? {};
121893
+ if (s.ticket && s.randstr) {
121894
+ return { ticket: s.ticket, randstr: s.randstr, appid: s.appid ?? input.appId };
121895
+ }
121896
+ return null;
121897
+ }
121898
+ } catch {
121899
+ return null;
121900
+ }
121901
+ await new Promise((r) => setTimeout(r, 2000));
121902
+ }
121903
+ return null;
121904
+ }
121905
+ async function submitWafClearance(input) {
121906
+ const doFetch = input.fetchImpl ?? fetch;
121907
+ const ret = input.ret ?? 0;
121908
+ const body = [String(ret), input.ticket, input.randstr, input.seqid].join(`
121909
+ `);
121910
+ const headers = { "Content-Type": "text/plain;charset=UTF-8" };
121911
+ if (input.cookieHeader)
121912
+ headers["Cookie"] = input.cookieHeader;
121913
+ try {
121914
+ const res = await doFetch(input.wafUrl, {
121915
+ method: "POST",
121916
+ headers,
121917
+ body,
121918
+ signal: AbortSignal.timeout(input.timeoutMs ?? 20000),
121919
+ ...input.proxyUrl ? { proxy: input.proxyUrl } : {}
121920
+ });
121921
+ const setCookies2 = typeof res.headers.getSetCookie === "function" ? res.headers.getSetCookie() : res.headers.get("set-cookie") ? [res.headers.get("set-cookie")] : [];
121922
+ return { ok: res.ok, status: res.status, setCookies: setCookies2 };
121923
+ } catch {
121924
+ return { ok: false, status: 0, setCookies: [] };
121925
+ }
121926
+ }
121927
+ function parseCapzyProxy(proxyUrl) {
121928
+ try {
121929
+ const u = new URL(proxyUrl);
121930
+ if (!u.hostname || !u.port)
121931
+ return;
121932
+ const scheme = u.protocol.replace(":", "").toLowerCase();
121933
+ const type = scheme === "socks5" || scheme === "socks4" || scheme === "https" ? scheme : "http";
121934
+ return {
121935
+ type,
121936
+ address: u.hostname,
121937
+ port: Number(u.port),
121938
+ ...u.username ? { login: decodeURIComponent(u.username) } : {},
121939
+ ...u.password ? { password: decodeURIComponent(u.password) } : {}
121940
+ };
121941
+ } catch {
121942
+ return;
121943
+ }
121944
+ }
121945
+ function mergeCookieHeader(prior, setCookies2) {
121946
+ const jar = new Map;
121947
+ for (const pair of (prior ?? "").split(/;\s*/)) {
121948
+ const eq2 = pair.indexOf("=");
121949
+ if (eq2 > 0)
121950
+ jar.set(pair.slice(0, eq2).trim(), pair.slice(eq2 + 1).trim());
121951
+ }
121952
+ for (const sc of setCookies2) {
121953
+ const first2 = sc.split(";")[0] ?? "";
121954
+ const eq2 = first2.indexOf("=");
121955
+ if (eq2 > 0)
121956
+ jar.set(first2.slice(0, eq2).trim(), first2.slice(eq2 + 1).trim());
121957
+ }
121958
+ return Array.from(jar, ([k, v]) => `${k}=${v}`).join("; ");
121959
+ }
121960
+ async function clearTencentWafViaCapzy(input) {
121961
+ const challenge = extractTencentChallenge(input.html);
121962
+ if (!challenge)
121963
+ return null;
121964
+ const solved = await solveTencentViaCapzy({
121965
+ websiteURL: input.url,
121966
+ appId: challenge.appId,
121967
+ clientKey: input.capzyKey,
121968
+ proxy: input.proxyUrl ? parseCapzyProxy(input.proxyUrl) : undefined,
121969
+ timeoutMs: input.timeoutMs,
121970
+ fetchImpl: input.fetchImpl
121971
+ });
121972
+ if (!solved)
121973
+ return null;
121974
+ let origin;
121975
+ try {
121976
+ origin = new URL(input.url).origin;
121977
+ } catch {
121978
+ return null;
121979
+ }
121980
+ const clearance = await submitWafClearance({
121981
+ wafUrl: `${origin}/WafCaptcha`,
121982
+ ticket: solved.ticket,
121983
+ randstr: solved.randstr,
121984
+ seqid: challenge.seqid,
121985
+ cookieHeader: input.cookieHeader,
121986
+ proxyUrl: input.proxyUrl,
121987
+ fetchImpl: input.fetchImpl
121988
+ });
121989
+ if (!clearance.ok)
121990
+ return null;
121991
+ const cookieHeader = mergeCookieHeader(input.cookieHeader, clearance.setCookies);
121992
+ const doFetch = input.fetchImpl ?? fetch;
121993
+ try {
121994
+ const res = await doFetch(input.url, {
121995
+ headers: { Cookie: cookieHeader, Accept: "*/*" },
121996
+ signal: AbortSignal.timeout(input.timeoutMs ?? 30000),
121997
+ ...input.proxyUrl ? { proxy: input.proxyUrl } : {}
121998
+ });
121999
+ const html3 = await res.text();
122000
+ if (!html3 || extractTencentChallenge(html3))
122001
+ return null;
122002
+ return { html: html3, cookieHeader };
122003
+ } catch {
122004
+ return null;
122005
+ }
122006
+ }
122007
+
122008
+ // .tmp-runtime-src/execution/capzy-cf-solve.ts
122009
+ function extractCfClearance(solution) {
122010
+ if (!solution || typeof solution !== "object")
122011
+ return null;
122012
+ const s = solution;
122013
+ const ua = typeof s.user_agent === "string" && s.user_agent || typeof s.userAgent === "string" && s.userAgent || undefined;
122014
+ if (typeof s.cf_clearance === "string" && s.cf_clearance) {
122015
+ return { cf_clearance: s.cf_clearance, user_agent: ua || undefined };
122016
+ }
122017
+ if (typeof s.token === "string" && s.token && s.type !== "turnstile") {
122018
+ return { cf_clearance: s.token, user_agent: ua || undefined };
122019
+ }
122020
+ const cookies = s.cookies;
122021
+ if (cookies && typeof cookies === "object" && !Array.isArray(cookies)) {
122022
+ const v = cookies.cf_clearance;
122023
+ if (typeof v === "string" && v)
122024
+ return { cf_clearance: v, user_agent: ua || undefined };
122025
+ }
122026
+ if (Array.isArray(cookies)) {
122027
+ for (const c of cookies) {
122028
+ if (c && typeof c === "object") {
122029
+ const o = c;
122030
+ if (o.name === "cf_clearance" && typeof o.value === "string" && o.value) {
122031
+ return { cf_clearance: o.value, user_agent: ua || undefined };
122032
+ }
122033
+ } else if (typeof c === "string" && c.startsWith("cf_clearance=")) {
122034
+ const v = c.slice("cf_clearance=".length).split(";")[0];
122035
+ if (v)
122036
+ return { cf_clearance: v, user_agent: ua || undefined };
122037
+ }
122038
+ }
122039
+ }
122040
+ return null;
122041
+ }
122042
+ function buildCfTask(websiteURL, proxy) {
122043
+ return {
122044
+ type: "AntiCloudflareTask",
122045
+ websiteURL,
122046
+ proxyType: proxy.type,
122047
+ proxyAddress: proxy.address,
122048
+ proxyPort: proxy.port,
122049
+ ...proxy.login ? { proxyLogin: proxy.login } : {},
122050
+ ...proxy.password ? { proxyPassword: proxy.password } : {}
122051
+ };
122052
+ }
122053
+ async function solveCfViaCapzy(input) {
122054
+ const clientKey = input.clientKey ?? process.env.UNBROWSE_CAPZY_KEY?.trim();
122055
+ if (!clientKey)
122056
+ return null;
122057
+ if (!input.proxy)
122058
+ return null;
122059
+ const apiBase = (input.apiBase ?? process.env.UNBROWSE_CAPZY_URL?.trim() ?? "https://api.capzy.ai").replace(/\/+$/, "");
122060
+ const doFetch = input.fetchImpl ?? fetch;
122061
+ const deadline = Date.now() + (input.timeoutMs ?? 120000);
122062
+ const task = buildCfTask(input.websiteURL, input.proxy);
122063
+ let taskId;
122064
+ try {
122065
+ const created = await doFetch(`${apiBase}/createTask`, {
122066
+ method: "POST",
122067
+ headers: { "Content-Type": "application/json" },
122068
+ body: JSON.stringify({ clientKey, task }),
122069
+ signal: AbortSignal.timeout(Math.max(1, Math.min(20000, deadline - Date.now())))
122070
+ });
122071
+ if (!created.ok)
122072
+ return null;
122073
+ const cj = await created.json().catch(() => null);
122074
+ if (!cj || cj.errorId || !cj.taskId)
122075
+ return null;
122076
+ taskId = cj.taskId;
122077
+ } catch {
122078
+ return null;
122079
+ }
122080
+ while (Date.now() < deadline) {
122081
+ try {
122082
+ const res = await doFetch(`${apiBase}/getTaskResult`, {
122083
+ method: "POST",
122084
+ headers: { "Content-Type": "application/json" },
122085
+ body: JSON.stringify({ clientKey, taskId }),
122086
+ signal: AbortSignal.timeout(Math.max(1, Math.min(15000, deadline - Date.now())))
122087
+ });
122088
+ if (!res.ok)
122089
+ return null;
122090
+ const rj = await res.json().catch(() => null);
122091
+ if (!rj || rj.errorId)
122092
+ return null;
122093
+ if (rj.status === "failed")
122094
+ return null;
122095
+ if (rj.status === "ready") {
122096
+ return extractCfClearance(rj.solution);
122097
+ }
122098
+ } catch {
122099
+ return null;
122100
+ }
122101
+ await new Promise((r) => setTimeout(r, 2500));
122102
+ }
122103
+ return null;
122104
+ }
122105
+ var init_capzy_cf_solve = () => {};
122106
+
121820
122107
  // .tmp-runtime-src/execution/cf-challenge.ts
121821
122108
  var exports_cf_challenge = {};
121822
122109
  __export(exports_cf_challenge, {
@@ -121837,6 +122124,31 @@ function extractCfBundleUrl(body, requestUrl) {
121837
122124
  }
121838
122125
  }
121839
122126
  async function solveCfAndRetry(input) {
122127
+ if (process.env.UNBROWSE_CAPZY_KEY?.trim()) {
122128
+ const viaCapzy = await solveCfViaCapzy({
122129
+ websiteURL: input.url,
122130
+ proxy: input.proxy ? parseCapzyProxy(input.proxy) : undefined,
122131
+ timeoutMs: input.timeoutMs
122132
+ });
122133
+ if (viaCapzy?.cf_clearance) {
122134
+ const merged2 = mergeCookieJar(input.cookies ?? [], [
122135
+ { name: "cf_clearance", value: viaCapzy.cf_clearance }
122136
+ ]);
122137
+ const cookieHeader2 = merged2.map((c) => `${c.name}=${c.value}`).join("; ");
122138
+ try {
122139
+ const retry = await globalThis.fetch(input.url, {
122140
+ method: "GET",
122141
+ headers: {
122142
+ ...cookieHeader2 ? { cookie: cookieHeader2 } : {},
122143
+ ...viaCapzy.user_agent ? { "user-agent": viaCapzy.user_agent } : {}
122144
+ }
122145
+ });
122146
+ if (retry.status >= 200 && retry.status < 400) {
122147
+ return { status: retry.status, html: await retry.text(), cookies: merged2 };
122148
+ }
122149
+ } catch {}
122150
+ }
122151
+ }
121840
122152
  const bundleUrl = extractCfBundleUrl(input.body, input.url);
121841
122153
  if (!bundleUrl)
121842
122154
  return null;
@@ -121918,6 +122230,7 @@ function mergeCookieJar(a, b) {
121918
122230
  var CF_BUNDLE_RE;
121919
122231
  var init_cf_challenge = __esm(() => {
121920
122232
  init_bundle_replay_client();
122233
+ init_capzy_cf_solve();
121921
122234
  CF_BUNDLE_RE = /src=["'](\/cdn-cgi\/challenge-platform\/h\/[gb]\/scripts\/jsd\/[a-f0-9]+\/main\.js)/i;
121922
122235
  });
121923
122236
 
@@ -144915,7 +145228,8 @@ async function recordAnalyticsSession2(payload) {
144915
145228
  return;
144916
145229
  await api3("POST", "/v1/analytics/sessions", {
144917
145230
  ...getTelemetryAttribution2(),
144918
- ...payload
145231
+ ...payload,
145232
+ install_id: getInstallId2()
144919
145233
  });
144920
145234
  }
144921
145235
  async function recordRoutingTelemetry2(events) {
@@ -148672,193 +148986,6 @@ function isGithubBlob(url) {
148672
148986
  return githubBlobToRaw(url) !== null;
148673
148987
  }
148674
148988
 
148675
- // .tmp-runtime-src/execution/tencent-waf-solve.ts
148676
- var exports_tencent_waf_solve = {};
148677
- __export(exports_tencent_waf_solve, {
148678
- submitWafClearance: () => submitWafClearance,
148679
- solveTencentViaCapzy: () => solveTencentViaCapzy,
148680
- parseCapzyProxy: () => parseCapzyProxy,
148681
- mergeCookieHeader: () => mergeCookieHeader,
148682
- extractTencentChallenge: () => extractTencentChallenge,
148683
- clearTencentWafViaCapzy: () => clearTencentWafViaCapzy
148684
- });
148685
- function extractTencentChallenge(html3) {
148686
- if (!html3 || typeof html3 !== "string")
148687
- return null;
148688
- const appMatch = html3.match(/new\s+Captcha\(\s*["']([0-9]{5,})["']/);
148689
- const seqMatch = html3.match(/var\s+seqid\s*=\s*["']([^"']+?)["']/);
148690
- if (!appMatch || !seqMatch)
148691
- return null;
148692
- return { appId: appMatch[1], seqid: seqMatch[1] };
148693
- }
148694
- async function solveTencentViaCapzy(input) {
148695
- const clientKey = input.clientKey ?? process.env.UNBROWSE_CAPZY_KEY?.trim();
148696
- if (!clientKey)
148697
- return null;
148698
- const apiBase = (input.apiBase ?? process.env.UNBROWSE_CAPZY_URL?.trim() ?? "https://api.capzy.ai").replace(/\/+$/, "");
148699
- const doFetch = input.fetchImpl ?? fetch;
148700
- const deadline = Date.now() + (input.timeoutMs ?? 90000);
148701
- const task = input.proxy ? {
148702
- type: "TencentTask",
148703
- websiteURL: input.websiteURL,
148704
- websiteKey: input.appId,
148705
- proxyType: input.proxy.type,
148706
- proxyAddress: input.proxy.address,
148707
- proxyPort: input.proxy.port,
148708
- ...input.proxy.login ? { proxyLogin: input.proxy.login } : {},
148709
- ...input.proxy.password ? { proxyPassword: input.proxy.password } : {}
148710
- } : {
148711
- type: "TencentTaskProxyLess",
148712
- websiteURL: input.websiteURL,
148713
- websiteKey: input.appId
148714
- };
148715
- let taskId;
148716
- try {
148717
- const created = await doFetch(`${apiBase}/createTask`, {
148718
- method: "POST",
148719
- headers: { "Content-Type": "application/json" },
148720
- body: JSON.stringify({ clientKey, task }),
148721
- signal: AbortSignal.timeout(Math.max(1, Math.min(20000, deadline - Date.now())))
148722
- });
148723
- if (!created.ok)
148724
- return null;
148725
- const cj = await created.json().catch(() => null);
148726
- if (!cj || cj.errorId || !cj.taskId)
148727
- return null;
148728
- taskId = cj.taskId;
148729
- } catch {
148730
- return null;
148731
- }
148732
- while (Date.now() < deadline) {
148733
- try {
148734
- const res = await doFetch(`${apiBase}/getTaskResult`, {
148735
- method: "POST",
148736
- headers: { "Content-Type": "application/json" },
148737
- body: JSON.stringify({ clientKey, taskId }),
148738
- signal: AbortSignal.timeout(Math.max(1, Math.min(15000, deadline - Date.now())))
148739
- });
148740
- if (!res.ok)
148741
- return null;
148742
- const rj = await res.json().catch(() => null);
148743
- if (!rj || rj.errorId)
148744
- return null;
148745
- if (rj.status === "ready") {
148746
- const s = rj.solution ?? {};
148747
- if (s.ticket && s.randstr) {
148748
- return { ticket: s.ticket, randstr: s.randstr, appid: s.appid ?? input.appId };
148749
- }
148750
- return null;
148751
- }
148752
- } catch {
148753
- return null;
148754
- }
148755
- await new Promise((r) => setTimeout(r, 2000));
148756
- }
148757
- return null;
148758
- }
148759
- async function submitWafClearance(input) {
148760
- const doFetch = input.fetchImpl ?? fetch;
148761
- const ret = input.ret ?? 0;
148762
- const body = [String(ret), input.ticket, input.randstr, input.seqid].join(`
148763
- `);
148764
- const headers = { "Content-Type": "text/plain;charset=UTF-8" };
148765
- if (input.cookieHeader)
148766
- headers["Cookie"] = input.cookieHeader;
148767
- try {
148768
- const res = await doFetch(input.wafUrl, {
148769
- method: "POST",
148770
- headers,
148771
- body,
148772
- signal: AbortSignal.timeout(input.timeoutMs ?? 20000),
148773
- ...input.proxyUrl ? { proxy: input.proxyUrl } : {}
148774
- });
148775
- const setCookies2 = typeof res.headers.getSetCookie === "function" ? res.headers.getSetCookie() : res.headers.get("set-cookie") ? [res.headers.get("set-cookie")] : [];
148776
- return { ok: res.ok, status: res.status, setCookies: setCookies2 };
148777
- } catch {
148778
- return { ok: false, status: 0, setCookies: [] };
148779
- }
148780
- }
148781
- function parseCapzyProxy(proxyUrl) {
148782
- try {
148783
- const u = new URL(proxyUrl);
148784
- if (!u.hostname || !u.port)
148785
- return;
148786
- const scheme = u.protocol.replace(":", "").toLowerCase();
148787
- const type = scheme === "socks5" || scheme === "socks4" || scheme === "https" ? scheme : "http";
148788
- return {
148789
- type,
148790
- address: u.hostname,
148791
- port: Number(u.port),
148792
- ...u.username ? { login: decodeURIComponent(u.username) } : {},
148793
- ...u.password ? { password: decodeURIComponent(u.password) } : {}
148794
- };
148795
- } catch {
148796
- return;
148797
- }
148798
- }
148799
- function mergeCookieHeader(prior, setCookies2) {
148800
- const jar = new Map;
148801
- for (const pair of (prior ?? "").split(/;\s*/)) {
148802
- const eq2 = pair.indexOf("=");
148803
- if (eq2 > 0)
148804
- jar.set(pair.slice(0, eq2).trim(), pair.slice(eq2 + 1).trim());
148805
- }
148806
- for (const sc of setCookies2) {
148807
- const first2 = sc.split(";")[0] ?? "";
148808
- const eq2 = first2.indexOf("=");
148809
- if (eq2 > 0)
148810
- jar.set(first2.slice(0, eq2).trim(), first2.slice(eq2 + 1).trim());
148811
- }
148812
- return Array.from(jar, ([k, v]) => `${k}=${v}`).join("; ");
148813
- }
148814
- async function clearTencentWafViaCapzy(input) {
148815
- const challenge = extractTencentChallenge(input.html);
148816
- if (!challenge)
148817
- return null;
148818
- const solved = await solveTencentViaCapzy({
148819
- websiteURL: input.url,
148820
- appId: challenge.appId,
148821
- clientKey: input.capzyKey,
148822
- proxy: input.proxyUrl ? parseCapzyProxy(input.proxyUrl) : undefined,
148823
- timeoutMs: input.timeoutMs,
148824
- fetchImpl: input.fetchImpl
148825
- });
148826
- if (!solved)
148827
- return null;
148828
- let origin;
148829
- try {
148830
- origin = new URL(input.url).origin;
148831
- } catch {
148832
- return null;
148833
- }
148834
- const clearance = await submitWafClearance({
148835
- wafUrl: `${origin}/WafCaptcha`,
148836
- ticket: solved.ticket,
148837
- randstr: solved.randstr,
148838
- seqid: challenge.seqid,
148839
- cookieHeader: input.cookieHeader,
148840
- proxyUrl: input.proxyUrl,
148841
- fetchImpl: input.fetchImpl
148842
- });
148843
- if (!clearance.ok)
148844
- return null;
148845
- const cookieHeader = mergeCookieHeader(input.cookieHeader, clearance.setCookies);
148846
- const doFetch = input.fetchImpl ?? fetch;
148847
- try {
148848
- const res = await doFetch(input.url, {
148849
- headers: { Cookie: cookieHeader, Accept: "*/*" },
148850
- signal: AbortSignal.timeout(input.timeoutMs ?? 30000),
148851
- ...input.proxyUrl ? { proxy: input.proxyUrl } : {}
148852
- });
148853
- const html3 = await res.text();
148854
- if (!html3 || extractTencentChallenge(html3))
148855
- return null;
148856
- return { html: html3, cookieHeader };
148857
- } catch {
148858
- return null;
148859
- }
148860
- }
148861
-
148862
148989
  // .tmp-runtime-src/extraction/readability.ts
148863
148990
  function linkDensity($2, $el) {
148864
148991
  const textLen = $el.text().replace(/\s+/g, " ").trim().length || 1;
Binary file
@@ -2,7 +2,7 @@
2
2
  "repo_url": "https://github.com/justrach/kuri.git",
3
3
  "branch": "adding-extensions",
4
4
  "source_sha": "149881254046a20778f642b69f20f0c6468f6fb4",
5
- "built_at": "2026-06-17T10:44:55.424Z",
5
+ "built_at": "2026-06-17T20:24:54.012Z",
6
6
  "binaries": {
7
7
  "darwin-arm64": {
8
8
  "zig_target": "aarch64-macos",
@@ -21,11 +21,11 @@
21
21
  },
22
22
  "linux-x64": {
23
23
  "zig_target": "x86_64-linux",
24
- "sha256": "3e4fb4be6173b561499b5342e4beb3c97c0d616a6926c6f53268643020f68a52"
24
+ "sha256": "63a56d1b15d5ea1f7fe5f37157a1a018cbd1a9308c8dd126a4992a8d05a9970c"
25
25
  },
26
26
  "win-x64": {
27
27
  "zig_target": "x86_64-windows-gnu",
28
- "sha256": "3ef1b1f21e3ec1a45c39916136178b79878dbc35c711490ef35d980501dd53d8",
28
+ "sha256": "24cf7b34a6d29b1bf9bd2dec1f616828cf88211a4c171b63b25265d467b93cb6",
29
29
  "source": "pre-staged"
30
30
  }
31
31
  },
@@ -33,22 +33,22 @@
33
33
  "darwin-arm64": {
34
34
  "zig_target": "aarch64-macos",
35
35
  "lib": "libkuri_ffi.dylib",
36
- "sha256": "9d243eb293dce21db443baf2bd742ad4933d5a260f09a4f4cdfe60a06093a32b"
36
+ "sha256": "3b2c830e62bfe76605bc1a0531f8af362cfaece72b3675511407c295f6768d1f"
37
37
  },
38
38
  "darwin-x64": {
39
39
  "zig_target": "x86_64-macos",
40
40
  "lib": "libkuri_ffi.dylib",
41
- "sha256": "05807d8b55540437f567d4b4b125195c29bf1e375771a51029f4a44f41a5075c"
41
+ "sha256": "b510792c338e0cc618e79cdacfe1b85258be9904d6768b089cc63ed561a631ba"
42
42
  },
43
43
  "linux-arm64": {
44
44
  "zig_target": "aarch64-linux",
45
45
  "lib": "libkuri_ffi.so",
46
- "sha256": "06d5add450b8833f83e9e537fb21cc9c34f1954dd1aa68ed5039458e264b4cfe"
46
+ "sha256": "72335f81d0a6048b7228fece8fcce861884a059fb0ac4475a5577b5fa9b02ccf"
47
47
  },
48
48
  "linux-x64": {
49
49
  "zig_target": "x86_64-linux",
50
50
  "lib": "libkuri_ffi.so",
51
- "sha256": "d16c209f2350bc6d21b06a2d8be68c8a264f444588266a9d3bbbb7b8e97e3aa7"
51
+ "sha256": "50db645f48c0d49d53733bc1eb099bc08a9a493c1f79f893566775700c504ecf"
52
52
  }
53
53
  }
54
54
  }
Binary file