unbrowse 9.5.0-preview.1 → 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.5.0-preview.1",
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.5.0-preview.1", BUILD_GIT_SHA = "77a00a93a3da", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiOS41LjAtcHJldmlldy4xIiwiZ2l0X3NoYSI6Ijc3YTAwYTkzYTNkYSIsImNvZGVfaGFzaCI6IjVkOWViZjYxOWM2MSIsInRyYWNlX3ZlcnNpb24iOiI1ZDllYmY2MTljNjFANzdhMDBhOTNhM2RhIiwiaXNzdWVkX2F0IjoiMjAyNi0wNi0xN1QxNjoyMjozNC41MjdaIn0", BUILD_RELEASE_MANIFEST_SIGNATURE = "S6SeRd9EuGt1SLhfbZOdCZbjCUsYF8E0D-Yx-cet33g", 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";
@@ -123597,6 +123597,125 @@ var init_fetch_ladder = __esm(() => {
123597
123597
  ];
123598
123598
  });
123599
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
+
123600
123719
  // .tmp-runtime-src/execution/cf-challenge.ts
123601
123720
  var exports_cf_challenge = {};
123602
123721
  __export(exports_cf_challenge, {
@@ -123617,6 +123736,31 @@ function extractCfBundleUrl(body, requestUrl) {
123617
123736
  }
123618
123737
  }
123619
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
+ }
123620
123764
  const bundleUrl = extractCfBundleUrl(input.body, input.url);
123621
123765
  if (!bundleUrl)
123622
123766
  return null;
@@ -123698,6 +123842,7 @@ function mergeCookieJar(a, b) {
123698
123842
  var CF_BUNDLE_RE;
123699
123843
  var init_cf_challenge = __esm(() => {
123700
123844
  init_bundle_replay_client();
123845
+ init_capzy_cf_solve();
123701
123846
  CF_BUNDLE_RE = /src=["'](\/cdn-cgi\/challenge-platform\/h\/[gb]\/scripts\/jsd\/[a-f0-9]+\/main\.js)/i;
123702
123847
  });
123703
123848
 
@@ -154011,7 +154156,7 @@ var exports_tencent_waf_solve = {};
154011
154156
  __export(exports_tencent_waf_solve, {
154012
154157
  submitWafClearance: () => submitWafClearance,
154013
154158
  solveTencentViaCapzy: () => solveTencentViaCapzy,
154014
- parseCapzyProxy: () => parseCapzyProxy,
154159
+ parseCapzyProxy: () => parseCapzyProxy2,
154015
154160
  mergeCookieHeader: () => mergeCookieHeader,
154016
154161
  extractTencentChallenge: () => extractTencentChallenge,
154017
154162
  clearTencentWafViaCapzy: () => clearTencentWafViaCapzy
@@ -154112,7 +154257,7 @@ async function submitWafClearance(input) {
154112
154257
  return { ok: false, status: 0, setCookies: [] };
154113
154258
  }
154114
154259
  }
154115
- function parseCapzyProxy(proxyUrl) {
154260
+ function parseCapzyProxy2(proxyUrl) {
154116
154261
  try {
154117
154262
  const u = new URL(proxyUrl);
154118
154263
  if (!u.hostname || !u.port)
@@ -154153,7 +154298,7 @@ async function clearTencentWafViaCapzy(input) {
154153
154298
  websiteURL: input.url,
154154
154299
  appId: challenge.appId,
154155
154300
  clientKey: input.capzyKey,
154156
- proxy: input.proxyUrl ? parseCapzyProxy(input.proxyUrl) : undefined,
154301
+ proxy: input.proxyUrl ? parseCapzyProxy2(input.proxyUrl) : undefined,
154157
154302
  timeoutMs: input.timeoutMs,
154158
154303
  fetchImpl: input.fetchImpl
154159
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.5.0-preview.1", BUILD_GIT_SHA = "77a00a93a3da", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiOS41LjAtcHJldmlldy4xIiwiZ2l0X3NoYSI6Ijc3YTAwYTkzYTNkYSIsImNvZGVfaGFzaCI6IjVkOWViZjYxOWM2MSIsInRyYWNlX3ZlcnNpb24iOiI1ZDllYmY2MTljNjFANzdhMDBhOTNhM2RhIiwiaXNzdWVkX2F0IjoiMjAyNi0wNi0xN1QxNjoyMjozNC41MjdaIn0", BUILD_RELEASE_MANIFEST_SIGNATURE = "S6SeRd9EuGt1SLhfbZOdCZbjCUsYF8E0D-Yx-cet33g", 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";
@@ -121818,6 +121818,292 @@ var init_fetch_ladder = __esm(() => {
121818
121818
  ];
121819
121819
  });
121820
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
+
121821
122107
  // .tmp-runtime-src/execution/cf-challenge.ts
121822
122108
  var exports_cf_challenge = {};
121823
122109
  __export(exports_cf_challenge, {
@@ -121838,6 +122124,31 @@ function extractCfBundleUrl(body, requestUrl) {
121838
122124
  }
121839
122125
  }
121840
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
+ }
121841
122152
  const bundleUrl = extractCfBundleUrl(input.body, input.url);
121842
122153
  if (!bundleUrl)
121843
122154
  return null;
@@ -121919,6 +122230,7 @@ function mergeCookieJar(a, b) {
121919
122230
  var CF_BUNDLE_RE;
121920
122231
  var init_cf_challenge = __esm(() => {
121921
122232
  init_bundle_replay_client();
122233
+ init_capzy_cf_solve();
121922
122234
  CF_BUNDLE_RE = /src=["'](\/cdn-cgi\/challenge-platform\/h\/[gb]\/scripts\/jsd\/[a-f0-9]+\/main\.js)/i;
121923
122235
  });
121924
122236
 
@@ -148674,193 +148986,6 @@ function isGithubBlob(url) {
148674
148986
  return githubBlobToRaw(url) !== null;
148675
148987
  }
148676
148988
 
148677
- // .tmp-runtime-src/execution/tencent-waf-solve.ts
148678
- var exports_tencent_waf_solve = {};
148679
- __export(exports_tencent_waf_solve, {
148680
- submitWafClearance: () => submitWafClearance,
148681
- solveTencentViaCapzy: () => solveTencentViaCapzy,
148682
- parseCapzyProxy: () => parseCapzyProxy,
148683
- mergeCookieHeader: () => mergeCookieHeader,
148684
- extractTencentChallenge: () => extractTencentChallenge,
148685
- clearTencentWafViaCapzy: () => clearTencentWafViaCapzy
148686
- });
148687
- function extractTencentChallenge(html3) {
148688
- if (!html3 || typeof html3 !== "string")
148689
- return null;
148690
- const appMatch = html3.match(/new\s+Captcha\(\s*["']([0-9]{5,})["']/);
148691
- const seqMatch = html3.match(/var\s+seqid\s*=\s*["']([^"']+?)["']/);
148692
- if (!appMatch || !seqMatch)
148693
- return null;
148694
- return { appId: appMatch[1], seqid: seqMatch[1] };
148695
- }
148696
- async function solveTencentViaCapzy(input) {
148697
- const clientKey = input.clientKey ?? process.env.UNBROWSE_CAPZY_KEY?.trim();
148698
- if (!clientKey)
148699
- return null;
148700
- const apiBase = (input.apiBase ?? process.env.UNBROWSE_CAPZY_URL?.trim() ?? "https://api.capzy.ai").replace(/\/+$/, "");
148701
- const doFetch = input.fetchImpl ?? fetch;
148702
- const deadline = Date.now() + (input.timeoutMs ?? 90000);
148703
- const task = input.proxy ? {
148704
- type: "TencentTask",
148705
- websiteURL: input.websiteURL,
148706
- websiteKey: input.appId,
148707
- proxyType: input.proxy.type,
148708
- proxyAddress: input.proxy.address,
148709
- proxyPort: input.proxy.port,
148710
- ...input.proxy.login ? { proxyLogin: input.proxy.login } : {},
148711
- ...input.proxy.password ? { proxyPassword: input.proxy.password } : {}
148712
- } : {
148713
- type: "TencentTaskProxyLess",
148714
- websiteURL: input.websiteURL,
148715
- websiteKey: input.appId
148716
- };
148717
- let taskId;
148718
- try {
148719
- const created = await doFetch(`${apiBase}/createTask`, {
148720
- method: "POST",
148721
- headers: { "Content-Type": "application/json" },
148722
- body: JSON.stringify({ clientKey, task }),
148723
- signal: AbortSignal.timeout(Math.max(1, Math.min(20000, deadline - Date.now())))
148724
- });
148725
- if (!created.ok)
148726
- return null;
148727
- const cj = await created.json().catch(() => null);
148728
- if (!cj || cj.errorId || !cj.taskId)
148729
- return null;
148730
- taskId = cj.taskId;
148731
- } catch {
148732
- return null;
148733
- }
148734
- while (Date.now() < deadline) {
148735
- try {
148736
- const res = await doFetch(`${apiBase}/getTaskResult`, {
148737
- method: "POST",
148738
- headers: { "Content-Type": "application/json" },
148739
- body: JSON.stringify({ clientKey, taskId }),
148740
- signal: AbortSignal.timeout(Math.max(1, Math.min(15000, deadline - Date.now())))
148741
- });
148742
- if (!res.ok)
148743
- return null;
148744
- const rj = await res.json().catch(() => null);
148745
- if (!rj || rj.errorId)
148746
- return null;
148747
- if (rj.status === "ready") {
148748
- const s = rj.solution ?? {};
148749
- if (s.ticket && s.randstr) {
148750
- return { ticket: s.ticket, randstr: s.randstr, appid: s.appid ?? input.appId };
148751
- }
148752
- return null;
148753
- }
148754
- } catch {
148755
- return null;
148756
- }
148757
- await new Promise((r) => setTimeout(r, 2000));
148758
- }
148759
- return null;
148760
- }
148761
- async function submitWafClearance(input) {
148762
- const doFetch = input.fetchImpl ?? fetch;
148763
- const ret = input.ret ?? 0;
148764
- const body = [String(ret), input.ticket, input.randstr, input.seqid].join(`
148765
- `);
148766
- const headers = { "Content-Type": "text/plain;charset=UTF-8" };
148767
- if (input.cookieHeader)
148768
- headers["Cookie"] = input.cookieHeader;
148769
- try {
148770
- const res = await doFetch(input.wafUrl, {
148771
- method: "POST",
148772
- headers,
148773
- body,
148774
- signal: AbortSignal.timeout(input.timeoutMs ?? 20000),
148775
- ...input.proxyUrl ? { proxy: input.proxyUrl } : {}
148776
- });
148777
- const setCookies2 = typeof res.headers.getSetCookie === "function" ? res.headers.getSetCookie() : res.headers.get("set-cookie") ? [res.headers.get("set-cookie")] : [];
148778
- return { ok: res.ok, status: res.status, setCookies: setCookies2 };
148779
- } catch {
148780
- return { ok: false, status: 0, setCookies: [] };
148781
- }
148782
- }
148783
- function parseCapzyProxy(proxyUrl) {
148784
- try {
148785
- const u = new URL(proxyUrl);
148786
- if (!u.hostname || !u.port)
148787
- return;
148788
- const scheme = u.protocol.replace(":", "").toLowerCase();
148789
- const type = scheme === "socks5" || scheme === "socks4" || scheme === "https" ? scheme : "http";
148790
- return {
148791
- type,
148792
- address: u.hostname,
148793
- port: Number(u.port),
148794
- ...u.username ? { login: decodeURIComponent(u.username) } : {},
148795
- ...u.password ? { password: decodeURIComponent(u.password) } : {}
148796
- };
148797
- } catch {
148798
- return;
148799
- }
148800
- }
148801
- function mergeCookieHeader(prior, setCookies2) {
148802
- const jar = new Map;
148803
- for (const pair of (prior ?? "").split(/;\s*/)) {
148804
- const eq2 = pair.indexOf("=");
148805
- if (eq2 > 0)
148806
- jar.set(pair.slice(0, eq2).trim(), pair.slice(eq2 + 1).trim());
148807
- }
148808
- for (const sc of setCookies2) {
148809
- const first2 = sc.split(";")[0] ?? "";
148810
- const eq2 = first2.indexOf("=");
148811
- if (eq2 > 0)
148812
- jar.set(first2.slice(0, eq2).trim(), first2.slice(eq2 + 1).trim());
148813
- }
148814
- return Array.from(jar, ([k, v]) => `${k}=${v}`).join("; ");
148815
- }
148816
- async function clearTencentWafViaCapzy(input) {
148817
- const challenge = extractTencentChallenge(input.html);
148818
- if (!challenge)
148819
- return null;
148820
- const solved = await solveTencentViaCapzy({
148821
- websiteURL: input.url,
148822
- appId: challenge.appId,
148823
- clientKey: input.capzyKey,
148824
- proxy: input.proxyUrl ? parseCapzyProxy(input.proxyUrl) : undefined,
148825
- timeoutMs: input.timeoutMs,
148826
- fetchImpl: input.fetchImpl
148827
- });
148828
- if (!solved)
148829
- return null;
148830
- let origin;
148831
- try {
148832
- origin = new URL(input.url).origin;
148833
- } catch {
148834
- return null;
148835
- }
148836
- const clearance = await submitWafClearance({
148837
- wafUrl: `${origin}/WafCaptcha`,
148838
- ticket: solved.ticket,
148839
- randstr: solved.randstr,
148840
- seqid: challenge.seqid,
148841
- cookieHeader: input.cookieHeader,
148842
- proxyUrl: input.proxyUrl,
148843
- fetchImpl: input.fetchImpl
148844
- });
148845
- if (!clearance.ok)
148846
- return null;
148847
- const cookieHeader = mergeCookieHeader(input.cookieHeader, clearance.setCookies);
148848
- const doFetch = input.fetchImpl ?? fetch;
148849
- try {
148850
- const res = await doFetch(input.url, {
148851
- headers: { Cookie: cookieHeader, Accept: "*/*" },
148852
- signal: AbortSignal.timeout(input.timeoutMs ?? 30000),
148853
- ...input.proxyUrl ? { proxy: input.proxyUrl } : {}
148854
- });
148855
- const html3 = await res.text();
148856
- if (!html3 || extractTencentChallenge(html3))
148857
- return null;
148858
- return { html: html3, cookieHeader };
148859
- } catch {
148860
- return null;
148861
- }
148862
- }
148863
-
148864
148989
  // .tmp-runtime-src/extraction/readability.ts
148865
148990
  function linkDensity($2, $el) {
148866
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-17T15:12:51.641Z",
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": "4d009a669b71c2e11d747fb2839da17b1f89b62b4e937a9f5bb7274cc2ee2b4a"
24
+ "sha256": "63a56d1b15d5ea1f7fe5f37157a1a018cbd1a9308c8dd126a4992a8d05a9970c"
25
25
  },
26
26
  "win-x64": {
27
27
  "zig_target": "x86_64-windows-gnu",
28
- "sha256": "4a244ea5f508b7dbeff9227f43458bb03e6db2e11f72abd00ab3c81c0fde973d",
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": "c49a5ad76c782f3fa351a8c8f797f63bf92a2e4f4405a76fc92d59cba9e52dee"
36
+ "sha256": "3b2c830e62bfe76605bc1a0531f8af362cfaece72b3675511407c295f6768d1f"
37
37
  },
38
38
  "darwin-x64": {
39
39
  "zig_target": "x86_64-macos",
40
40
  "lib": "libkuri_ffi.dylib",
41
- "sha256": "44ef8a02fa2e3f70f52cfb915cc2cf69e321964770c3fcdaaa9906341044fa5d"
41
+ "sha256": "b510792c338e0cc618e79cdacfe1b85258be9904d6768b089cc63ed561a631ba"
42
42
  },
43
43
  "linux-arm64": {
44
44
  "zig_target": "aarch64-linux",
45
45
  "lib": "libkuri_ffi.so",
46
- "sha256": "18a8c9834bfd1090d29d9ea20426dc8b798a7eb0c3a64949cefe0ef83551a7e3"
46
+ "sha256": "72335f81d0a6048b7228fece8fcce861884a059fb0ac4475a5577b5fa9b02ccf"
47
47
  },
48
48
  "linux-x64": {
49
49
  "zig_target": "x86_64-linux",
50
50
  "lib": "libkuri_ffi.so",
51
- "sha256": "9c874005b5d4b32ed52999a68a4f5961b304e072cf152bac28aa86351d662ac7"
51
+ "sha256": "50db645f48c0d49d53733bc1eb099bc08a9a493c1f79f893566775700c504ecf"
52
52
  }
53
53
  }
54
54
  }
Binary file