unbrowse 8.3.0-preview.6 → 8.3.1

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": "8.3.0-preview.6",
3
+ "version": "8.3.1",
4
4
  "description": "Reverse-engineer any website into reusable API skills. Zero-dep single binary with embedded browser engine.",
5
5
  "mcpName": "io.github.unbrowse-ai/unbrowse",
6
6
  "type": "module",
package/runtime/cli.js CHANGED
@@ -1102,7 +1102,7 @@ var init_cached_resolution = __esm(() => {
1102
1102
  });
1103
1103
 
1104
1104
  // .tmp-runtime-src/build-info.generated.ts
1105
- var BUILD_RELEASE_VERSION = "8.3.0-preview.6", BUILD_GIT_SHA = "325617c3e515", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiOC4zLjAtcHJldmlldy42IiwiZ2l0X3NoYSI6IjMyNTYxN2MzZTUxNSIsImNvZGVfaGFzaCI6IjVkOWViZjYxOWM2MSIsInRyYWNlX3ZlcnNpb24iOiI1ZDllYmY2MTljNjFAMzI1NjE3YzNlNTE1IiwiaXNzdWVkX2F0IjoiMjAyNi0wNi0xMlQxMzo0Nzo1MC4yMzZaIn0", BUILD_RELEASE_MANIFEST_SIGNATURE = "3Q3M5o0vC3jHpAsbTIFy1nQ0wPMAm3mfsbKJmtPXFoo", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai", BUILD_DEFAULT_PROFILE = "";
1105
+ var BUILD_RELEASE_VERSION = "8.3.1", BUILD_GIT_SHA = "6ea31d441793", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiOC4zLjEiLCJnaXRfc2hhIjoiNmVhMzFkNDQxNzkzIiwiY29kZV9oYXNoIjoiNWQ5ZWJmNjE5YzYxIiwidHJhY2VfdmVyc2lvbiI6IjVkOWViZjYxOWM2MUA2ZWEzMWQ0NDE3OTMiLCJpc3N1ZWRfYXQiOiIyMDI2LTA2LTEyVDE1OjI4OjQ5LjgyMFoifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "Q6Fdw7LvHNTYWpn0jp9F7Dg5I4VbJASjXq_7qk6xXh8", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai", BUILD_DEFAULT_PROFILE = "";
1106
1106
 
1107
1107
  // .tmp-runtime-src/version.ts
1108
1108
  import { createHash as createHash2 } from "crypto";
@@ -165677,6 +165677,72 @@ var init_publish = __esm(() => {
165677
165677
  init_sanitize();
165678
165678
  });
165679
165679
 
165680
+ // .tmp-runtime-src/capture/fetch-ladder.ts
165681
+ var exports_fetch_ladder = {};
165682
+ __export(exports_fetch_ladder, {
165683
+ walkFetchLadder: () => walkFetchLadder,
165684
+ looksBlocked: () => looksBlocked
165685
+ });
165686
+ function looksBlocked(text3, minBytes = 512) {
165687
+ if (!text3)
165688
+ return true;
165689
+ const t = text3.trim();
165690
+ const low = t.toLowerCase();
165691
+ if (BLOCK_PHRASES.some((p) => low.includes(p)))
165692
+ return true;
165693
+ if (t.length < minBytes)
165694
+ return true;
165695
+ return false;
165696
+ }
165697
+ async function walkFetchLadder(url, cookies) {
165698
+ for (const rung of FETCH_LADDER) {
165699
+ try {
165700
+ const r = await rung.run(url, cookies);
165701
+ if (r && r.status >= 200 && r.status < 400 && !looksBlocked(r.text)) {
165702
+ return { rung: rung.name, text: r.text, bytes: r.bytes, status: r.status };
165703
+ }
165704
+ } catch {}
165705
+ }
165706
+ return null;
165707
+ }
165708
+ var BLOCK_PHRASES, FETCH_LADDER;
165709
+ var init_fetch_ladder = __esm(() => {
165710
+ init_curl_impersonate_fallback();
165711
+ init_proxy_fetch();
165712
+ BLOCK_PHRASES = [
165713
+ "blocked by network security",
165714
+ "you've been blocked",
165715
+ "you have been blocked",
165716
+ "attention required",
165717
+ "verify you are human",
165718
+ "checking your browser",
165719
+ "enable javascript and cookies",
165720
+ "request unsuccessful. incapsula",
165721
+ "access denied",
165722
+ "ddos protection by",
165723
+ "just a moment"
165724
+ ];
165725
+ FETCH_LADDER = [
165726
+ {
165727
+ name: "impersonate-direct",
165728
+ run: async (url, cookies) => {
165729
+ const r = await tryCurlImpersonateFetch({ url, timeoutMs: 12000, forceDirect: true, cookies });
165730
+ return r && r.html ? { text: r.html, bytes: r.bytes, status: r.status } : null;
165731
+ }
165732
+ },
165733
+ {
165734
+ name: "impersonate-proxy",
165735
+ run: async (url, cookies) => {
165736
+ const proxy = resolveProxyUrl();
165737
+ if (!proxy)
165738
+ return null;
165739
+ const r = await tryCurlImpersonateFetch({ url, timeoutMs: 45000, proxy, cookies });
165740
+ return r && r.html ? { text: r.html, bytes: r.bytes, status: r.status } : null;
165741
+ }
165742
+ }
165743
+ ];
165744
+ });
165745
+
165680
165746
  // .tmp-runtime-src/execution/cf-challenge.ts
165681
165747
  var exports_cf_challenge = {};
165682
165748
  __export(exports_cf_challenge, {
@@ -167597,6 +167663,19 @@ async function executeBrowserCapture(skill, params, options) {
167597
167663
  };
167598
167664
  }
167599
167665
  }
167666
+ try {
167667
+ const { looksBlocked: looksBlocked2, walkFetchLadder: walkFetchLadder2 } = await Promise.resolve().then(() => (init_fetch_ladder(), exports_fetch_ladder));
167668
+ if (looksBlocked2(captured.html)) {
167669
+ const ladderCookies = (cookies ?? []).map((c) => ({ name: c.name, value: c.value }));
167670
+ const rescued = await walkFetchLadder2(captured.final_url ?? url, ladderCookies);
167671
+ if (rescued && !looksBlocked2(rescued.text)) {
167672
+ captured.html = rescued.text;
167673
+ log("execution", `fetch_ladder_unblocked: ${rescued.rung} ${rescued.bytes}B replaced block page`);
167674
+ }
167675
+ }
167676
+ } catch (err) {
167677
+ log("execution", `fetch_ladder_skip: ${err instanceof Error ? err.message : String(err)}`);
167678
+ }
167600
167679
  const extractionTrace = {};
167601
167680
  const endpoints = extractEndpoints(captured.requests, captured.ws_messages, { pageUrl: url, finalUrl: captured.final_url, intent }, extractionTrace);
167602
167681
  const computeCapturedMeta = () => {
@@ -184896,6 +184975,34 @@ ${text3}` : text3;
184896
184975
  page = { text: augmented, structured_data: structured };
184897
184976
  }
184898
184977
  } catch {}
184978
+ try {
184979
+ const ladder = await Promise.resolve().then(() => (init_fetch_ladder(), exports_fetch_ladder));
184980
+ if (!page || ladder.looksBlocked(page.text)) {
184981
+ let rescueCookies = [];
184982
+ try {
184983
+ const host = new URL(session.url).host;
184984
+ const { extractBrowserCookies: extractBrowserCookies2 } = await Promise.resolve().then(() => (init_browser_cookies(), exports_browser_cookies));
184985
+ rescueCookies = extractBrowserCookies2(host).cookies.map((c) => ({ name: c.name, value: c.value }));
184986
+ } catch {}
184987
+ const rescued = await ladder.walkFetchLadder(session.url, rescueCookies);
184988
+ if (rescued) {
184989
+ let structured = null;
184990
+ try {
184991
+ if (rescued.text.startsWith("<"))
184992
+ structured = buildStructuredDataHeader(rescued.text);
184993
+ } catch {}
184994
+ const augmented = structured ? `${structured}
184995
+
184996
+ ---
184997
+
184998
+ ${rescued.text}` : rescued.text;
184999
+ page = { text: augmented, structured_data: structured };
185000
+ console.log(`[browse/go] anti-bot block bypassed via fetch-ladder ${rescued.rung} (${rescued.bytes}B)`);
185001
+ }
185002
+ }
185003
+ } catch (err) {
185004
+ console.error(`[browse/go] fetch-ladder rescue failed (non-fatal): ${err.message}`);
185005
+ }
184899
185006
  let spool_written = false;
184900
185007
  try {
184901
185008
  const spoolRes = await spoolBrowseCapture(session, page ? { pageHtml: page.text } : {});
package/runtime/mcp.js CHANGED
@@ -38032,7 +38032,7 @@ var init_cached_resolution = __esm(() => {
38032
38032
  });
38033
38033
 
38034
38034
  // .tmp-runtime-src/build-info.generated.ts
38035
- var BUILD_RELEASE_VERSION = "8.3.0-preview.6", BUILD_GIT_SHA = "325617c3e515", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiOC4zLjAtcHJldmlldy42IiwiZ2l0X3NoYSI6IjMyNTYxN2MzZTUxNSIsImNvZGVfaGFzaCI6IjVkOWViZjYxOWM2MSIsInRyYWNlX3ZlcnNpb24iOiI1ZDllYmY2MTljNjFAMzI1NjE3YzNlNTE1IiwiaXNzdWVkX2F0IjoiMjAyNi0wNi0xMlQxMzo0Nzo1MC4yMzZaIn0", BUILD_RELEASE_MANIFEST_SIGNATURE = "3Q3M5o0vC3jHpAsbTIFy1nQ0wPMAm3mfsbKJmtPXFoo", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai", BUILD_DEFAULT_PROFILE = "";
38035
+ var BUILD_RELEASE_VERSION = "8.3.1", BUILD_GIT_SHA = "6ea31d441793", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiOC4zLjEiLCJnaXRfc2hhIjoiNmVhMzFkNDQxNzkzIiwiY29kZV9oYXNoIjoiNWQ5ZWJmNjE5YzYxIiwidHJhY2VfdmVyc2lvbiI6IjVkOWViZjYxOWM2MUA2ZWEzMWQ0NDE3OTMiLCJpc3N1ZWRfYXQiOiIyMDI2LTA2LTEyVDE1OjI4OjQ5LjgyMFoifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "Q6Fdw7LvHNTYWpn0jp9F7Dg5I4VbJASjXq_7qk6xXh8", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai", BUILD_DEFAULT_PROFILE = "";
38036
38036
 
38037
38037
  // .tmp-runtime-src/version.ts
38038
38038
  import { createHash as createHash2 } from "crypto";
@@ -96388,6 +96388,72 @@ var init_publish = __esm(() => {
96388
96388
  init_sanitize();
96389
96389
  });
96390
96390
 
96391
+ // .tmp-runtime-src/capture/fetch-ladder.ts
96392
+ var exports_fetch_ladder = {};
96393
+ __export(exports_fetch_ladder, {
96394
+ walkFetchLadder: () => walkFetchLadder,
96395
+ looksBlocked: () => looksBlocked
96396
+ });
96397
+ function looksBlocked(text3, minBytes = 512) {
96398
+ if (!text3)
96399
+ return true;
96400
+ const t = text3.trim();
96401
+ const low = t.toLowerCase();
96402
+ if (BLOCK_PHRASES.some((p) => low.includes(p)))
96403
+ return true;
96404
+ if (t.length < minBytes)
96405
+ return true;
96406
+ return false;
96407
+ }
96408
+ async function walkFetchLadder(url, cookies) {
96409
+ for (const rung of FETCH_LADDER) {
96410
+ try {
96411
+ const r = await rung.run(url, cookies);
96412
+ if (r && r.status >= 200 && r.status < 400 && !looksBlocked(r.text)) {
96413
+ return { rung: rung.name, text: r.text, bytes: r.bytes, status: r.status };
96414
+ }
96415
+ } catch {}
96416
+ }
96417
+ return null;
96418
+ }
96419
+ var BLOCK_PHRASES, FETCH_LADDER;
96420
+ var init_fetch_ladder = __esm(() => {
96421
+ init_curl_impersonate_fallback();
96422
+ init_proxy_fetch();
96423
+ BLOCK_PHRASES = [
96424
+ "blocked by network security",
96425
+ "you've been blocked",
96426
+ "you have been blocked",
96427
+ "attention required",
96428
+ "verify you are human",
96429
+ "checking your browser",
96430
+ "enable javascript and cookies",
96431
+ "request unsuccessful. incapsula",
96432
+ "access denied",
96433
+ "ddos protection by",
96434
+ "just a moment"
96435
+ ];
96436
+ FETCH_LADDER = [
96437
+ {
96438
+ name: "impersonate-direct",
96439
+ run: async (url, cookies) => {
96440
+ const r = await tryCurlImpersonateFetch({ url, timeoutMs: 12000, forceDirect: true, cookies });
96441
+ return r && r.html ? { text: r.html, bytes: r.bytes, status: r.status } : null;
96442
+ }
96443
+ },
96444
+ {
96445
+ name: "impersonate-proxy",
96446
+ run: async (url, cookies) => {
96447
+ const proxy = resolveProxyUrl();
96448
+ if (!proxy)
96449
+ return null;
96450
+ const r = await tryCurlImpersonateFetch({ url, timeoutMs: 45000, proxy, cookies });
96451
+ return r && r.html ? { text: r.html, bytes: r.bytes, status: r.status } : null;
96452
+ }
96453
+ }
96454
+ ];
96455
+ });
96456
+
96391
96457
  // .tmp-runtime-src/execution/cf-challenge.ts
96392
96458
  var exports_cf_challenge = {};
96393
96459
  __export(exports_cf_challenge, {
@@ -98308,6 +98374,19 @@ async function executeBrowserCapture(skill, params, options) {
98308
98374
  };
98309
98375
  }
98310
98376
  }
98377
+ try {
98378
+ const { looksBlocked: looksBlocked2, walkFetchLadder: walkFetchLadder2 } = await Promise.resolve().then(() => (init_fetch_ladder(), exports_fetch_ladder));
98379
+ if (looksBlocked2(captured.html)) {
98380
+ const ladderCookies = (cookies ?? []).map((c) => ({ name: c.name, value: c.value }));
98381
+ const rescued = await walkFetchLadder2(captured.final_url ?? url, ladderCookies);
98382
+ if (rescued && !looksBlocked2(rescued.text)) {
98383
+ captured.html = rescued.text;
98384
+ log("execution", `fetch_ladder_unblocked: ${rescued.rung} ${rescued.bytes}B replaced block page`);
98385
+ }
98386
+ }
98387
+ } catch (err) {
98388
+ log("execution", `fetch_ladder_skip: ${err instanceof Error ? err.message : String(err)}`);
98389
+ }
98311
98390
  const extractionTrace = {};
98312
98391
  const endpoints = extractEndpoints(captured.requests, captured.ws_messages, { pageUrl: url, finalUrl: captured.final_url, intent }, extractionTrace);
98313
98392
  const computeCapturedMeta = () => {
@@ -132084,6 +132163,34 @@ ${text3}` : text3;
132084
132163
  page = { text: augmented, structured_data: structured };
132085
132164
  }
132086
132165
  } catch {}
132166
+ try {
132167
+ const ladder = await Promise.resolve().then(() => (init_fetch_ladder(), exports_fetch_ladder));
132168
+ if (!page || ladder.looksBlocked(page.text)) {
132169
+ let rescueCookies = [];
132170
+ try {
132171
+ const host = new URL(session.url).host;
132172
+ const { extractBrowserCookies: extractBrowserCookies2 } = await Promise.resolve().then(() => (init_browser_cookies(), exports_browser_cookies));
132173
+ rescueCookies = extractBrowserCookies2(host).cookies.map((c) => ({ name: c.name, value: c.value }));
132174
+ } catch {}
132175
+ const rescued = await ladder.walkFetchLadder(session.url, rescueCookies);
132176
+ if (rescued) {
132177
+ let structured = null;
132178
+ try {
132179
+ if (rescued.text.startsWith("<"))
132180
+ structured = buildStructuredDataHeader(rescued.text);
132181
+ } catch {}
132182
+ const augmented = structured ? `${structured}
132183
+
132184
+ ---
132185
+
132186
+ ${rescued.text}` : rescued.text;
132187
+ page = { text: augmented, structured_data: structured };
132188
+ console.log(`[browse/go] anti-bot block bypassed via fetch-ladder ${rescued.rung} (${rescued.bytes}B)`);
132189
+ }
132190
+ }
132191
+ } catch (err) {
132192
+ console.error(`[browse/go] fetch-ladder rescue failed (non-fatal): ${err.message}`);
132193
+ }
132087
132194
  let spool_written = false;
132088
132195
  try {
132089
132196
  const spoolRes = await spoolBrowseCapture(session, page ? { pageHtml: page.text } : {});
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": "8938f89f3d0c032bd19c59db0de4eadca18a1800",
5
- "built_at": "2026-06-12T13:28:04.097Z",
5
+ "built_at": "2026-06-12T15:07:36.848Z",
6
6
  "binaries": {
7
7
  "darwin-arm64": {
8
8
  "zig_target": "aarch64-macos",
@@ -21,33 +21,33 @@
21
21
  },
22
22
  "linux-x64": {
23
23
  "zig_target": "x86_64-linux",
24
- "sha256": "c449829f6fb3e0ee2249fa387049e1e9780ace6df7899100d9193da8fddb8bf0"
24
+ "sha256": "5b86a8a9fe9b72a5cda002d0460c07fd0fc3406bbe037dcdfa13b82f4ed1bc74"
25
25
  },
26
26
  "win-x64": {
27
27
  "zig_target": "x86_64-windows-gnu",
28
- "sha256": "45fb825a4466d8f17a0db71dba083b5c9730dcf7ac32011b0a6e37e8d395d1de"
28
+ "sha256": "952debc58060b34d18ff73e703d669b2b8bf7faa9a45b9cbad1f0bb08c300d96"
29
29
  }
30
30
  },
31
31
  "ffi": {
32
32
  "darwin-arm64": {
33
33
  "zig_target": "aarch64-macos",
34
34
  "lib": "libkuri_ffi.dylib",
35
- "sha256": "455b47ac7d4b9781e755ab015a573dfa16b4c8e985953c1573c5f9900eed0bce"
35
+ "sha256": "40ee7c5d85c594bb60f692625235ef9bc878ef504a5c8782f61c002d2baae347"
36
36
  },
37
37
  "darwin-x64": {
38
38
  "zig_target": "x86_64-macos",
39
39
  "lib": "libkuri_ffi.dylib",
40
- "sha256": "f3a2f791432426d44791a49fa572140ff829be91cd83b2e64f65aaaffd1551c1"
40
+ "sha256": "c7b596a5260cc9b03da3073fff36c3d5e9ba1d121b807b125aacafdb80008ccf"
41
41
  },
42
42
  "linux-arm64": {
43
43
  "zig_target": "aarch64-linux",
44
44
  "lib": "libkuri_ffi.so",
45
- "sha256": "8899a6aa772fd8d3db829f5dff0c1f8822babf62974d3fb2c3d6c48119b77de7"
45
+ "sha256": "986b93a632a3e5f5a542382a76615c354d4e861f919aaa9aa29e7c8fcc40a68c"
46
46
  },
47
47
  "linux-x64": {
48
48
  "zig_target": "x86_64-linux",
49
49
  "lib": "libkuri_ffi.so",
50
- "sha256": "a4b21956a52fab10f6eb8c439f73842152d262c303d950de6ff030f899b33a31"
50
+ "sha256": "c5aab851c1ce7965f86e798e52bd624148c7680d8080381fb236823b13c2255b"
51
51
  }
52
52
  }
53
53
  }
Binary file