unbrowse 3.7.1 → 3.8.0-preview.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/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 = "3.7.1", BUILD_GIT_SHA = "90d1969f3abe", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy43LjEiLCJnaXRfc2hhIjoiOTBkMTk2OWYzYWJlIiwiY29kZV9oYXNoIjoiNWQ5ZWJmNjE5YzYxIiwidHJhY2VfdmVyc2lvbiI6IjVkOWViZjYxOWM2MUA5MGQxOTY5ZjNhYmUiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTEwVDA4OjQyOjEwLjg1NloifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "R5-PEYUVNGWtRmubf9WAMDDuH1_C2N6D4xteuGelBIM", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
34
+ var BUILD_RELEASE_VERSION = "3.8.0-preview.1", BUILD_GIT_SHA = "5b9633fd977c", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy44LjAtcHJldmlldy4xIiwiZ2l0X3NoYSI6IjViOTYzM2ZkOTc3YyIsImNvZGVfaGFzaCI6IjVkOWViZjYxOWM2MSIsInRyYWNlX3ZlcnNpb24iOiI1ZDllYmY2MTljNjFANWI5NjMzZmQ5NzdjIiwiaXNzdWVkX2F0IjoiMjAyNi0wNC0xMFQxNjo0NjoxMy4yMTFaIn0", BUILD_RELEASE_MANIFEST_SIGNATURE = "CR3byJyWyomilicbi2WBO0kBuXqbATk49Z5ZP9B0lz8", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
35
35
 
36
36
  // ../../src/version.ts
37
37
  import { createHash } from "crypto";
@@ -1183,6 +1183,9 @@ async function getDefaultTabOn(state) {
1183
1183
  async function start(port, state = defaultBrokerState) {
1184
1184
  return startOn(state, port);
1185
1185
  }
1186
+ async function stop(state = defaultBrokerState) {
1187
+ return stopOn(state);
1188
+ }
1186
1189
  async function getDefaultTab(state = defaultBrokerState) {
1187
1190
  return getDefaultTabOn(state);
1188
1191
  }
@@ -3499,7 +3502,11 @@ async function bootstrapAgentMailKey() {
3499
3502
  success: false,
3500
3503
  error: "Reached dashboard but could not extract API key. Create one manually at https://console.agentmail.to/dashboard/api-keys"
3501
3504
  };
3502
- } finally {}
3505
+ } finally {
3506
+ try {
3507
+ await stop();
3508
+ } catch {}
3509
+ }
3503
3510
  }
3504
3511
  function persistApiKeyToShell(apiKey) {
3505
3512
  const shell = process.env.SHELL ?? "/bin/zsh";
package/dist/mcp.js CHANGED
@@ -225,11 +225,11 @@ import { dirname, join, parse } from "path";
225
225
  import { fileURLToPath as fileURLToPath2 } from "url";
226
226
 
227
227
  // ../../src/build-info.generated.ts
228
- var BUILD_RELEASE_VERSION = "3.7.1";
229
- var BUILD_GIT_SHA = "90d1969f3abe";
228
+ var BUILD_RELEASE_VERSION = "3.8.0-preview.1";
229
+ var BUILD_GIT_SHA = "5b9633fd977c";
230
230
  var BUILD_CODE_HASH = "5d9ebf619c61";
231
- var BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy43LjEiLCJnaXRfc2hhIjoiOTBkMTk2OWYzYWJlIiwiY29kZV9oYXNoIjoiNWQ5ZWJmNjE5YzYxIiwidHJhY2VfdmVyc2lvbiI6IjVkOWViZjYxOWM2MUA5MGQxOTY5ZjNhYmUiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTEwVDA4OjQyOjEwLjg1NloifQ";
232
- var BUILD_RELEASE_MANIFEST_SIGNATURE = "R5-PEYUVNGWtRmubf9WAMDDuH1_C2N6D4xteuGelBIM";
231
+ var BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy44LjAtcHJldmlldy4xIiwiZ2l0X3NoYSI6IjViOTYzM2ZkOTc3YyIsImNvZGVfaGFzaCI6IjVkOWViZjYxOWM2MSIsInRyYWNlX3ZlcnNpb24iOiI1ZDllYmY2MTljNjFANWI5NjMzZmQ5NzdjIiwiaXNzdWVkX2F0IjoiMjAyNi0wNC0xMFQxNjo0NjoxMy4yMTFaIn0";
232
+ var BUILD_RELEASE_MANIFEST_SIGNATURE = "CR3byJyWyomilicbi2WBO0kBuXqbATk49Z5ZP9B0lz8";
233
233
  var BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
234
234
 
235
235
  // ../../src/version.ts
package/dist/server.js CHANGED
@@ -7120,7 +7120,7 @@ var init_capture = __esm(async () => {
7120
7120
  });
7121
7121
 
7122
7122
  // ../../src/build-info.generated.ts
7123
- var BUILD_RELEASE_VERSION = "3.7.1", BUILD_GIT_SHA = "90d1969f3abe", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy43LjEiLCJnaXRfc2hhIjoiOTBkMTk2OWYzYWJlIiwiY29kZV9oYXNoIjoiNWQ5ZWJmNjE5YzYxIiwidHJhY2VfdmVyc2lvbiI6IjVkOWViZjYxOWM2MUA5MGQxOTY5ZjNhYmUiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTEwVDA4OjQyOjEwLjg1NloifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "R5-PEYUVNGWtRmubf9WAMDDuH1_C2N6D4xteuGelBIM", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
7123
+ var BUILD_RELEASE_VERSION = "3.8.0-preview.1", BUILD_GIT_SHA = "5b9633fd977c", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy44LjAtcHJldmlldy4xIiwiZ2l0X3NoYSI6IjViOTYzM2ZkOTc3YyIsImNvZGVfaGFzaCI6IjVkOWViZjYxOWM2MSIsInRyYWNlX3ZlcnNpb24iOiI1ZDllYmY2MTljNjFANWI5NjMzZmQ5NzdjIiwiaXNzdWVkX2F0IjoiMjAyNi0wNC0xMFQxNjo0NjoxMy4yMTFaIn0", BUILD_RELEASE_MANIFEST_SIGNATURE = "CR3byJyWyomilicbi2WBO0kBuXqbATk49Z5ZP9B0lz8", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
7124
7124
 
7125
7125
  // ../../src/version.ts
7126
7126
  import { createHash as createHash2 } from "crypto";
@@ -16839,6 +16839,56 @@ async function executeBrowserCapture(skill, params, options) {
16839
16839
  }
16840
16840
  };
16841
16841
  }
16842
+ const antiBotSignal = (() => {
16843
+ const html = captured.html ?? "";
16844
+ if (!html)
16845
+ return "empty_capture";
16846
+ const lower = html.toLowerCase();
16847
+ const titleMatch = lower.match(/<title[^>]*>([^<]{0,200})<\/title>/);
16848
+ const title = titleMatch ? titleMatch[1].trim() : "";
16849
+ const blockTitles = [
16850
+ "robot check",
16851
+ "access denied",
16852
+ "just a moment",
16853
+ "attention required",
16854
+ "please verify",
16855
+ "security check",
16856
+ "are you a robot"
16857
+ ];
16858
+ for (const marker of blockTitles) {
16859
+ if (title.includes(marker))
16860
+ return `anti_bot_title:${marker}`;
16861
+ }
16862
+ const authTitles = ["log in", "sign in", "log in to", "sign in to"];
16863
+ if (authTitles.some((t) => title === t || title.startsWith(t + " ")) || title === "login") {
16864
+ return `auth_wall_title:${title}`;
16865
+ }
16866
+ if (lower.includes("g-recaptcha") || lower.includes("hcaptcha.com") || lower.includes("cf-challenge-form")) {
16867
+ return "captcha_present";
16868
+ }
16869
+ if (html.length < 5000 && !lower.includes("<script")) {
16870
+ return `tiny_body:${html.length}b`;
16871
+ }
16872
+ return null;
16873
+ })();
16874
+ if (antiBotSignal) {
16875
+ const trace3 = stampTrace({
16876
+ trace_id: traceId,
16877
+ skill_id: skill.skill_id,
16878
+ endpoint_id: "browser-capture",
16879
+ started_at: startedAt,
16880
+ completed_at: new Date().toISOString(),
16881
+ success: false,
16882
+ error: "browser_block"
16883
+ });
16884
+ return {
16885
+ trace: trace3,
16886
+ result: {
16887
+ error: "browser_block",
16888
+ message: `Browser capture detected a block signal at ${url}: ${antiBotSignal}. The site served a degraded/challenge page to the headless browser. Real-browser cookies via autoExtract may be required.`
16889
+ }
16890
+ };
16891
+ }
16842
16892
  const trace2 = stampTrace({
16843
16893
  trace_id: traceId,
16844
16894
  skill_id: skill.skill_id,
@@ -22339,25 +22389,45 @@ async function resolveAndExecute(intent, params = {}, context, projection, optio
22339
22389
  redirect: "follow"
22340
22390
  });
22341
22391
  const ct = directRes.headers.get("content-type") ?? "";
22342
- if (directRes.ok && (ct.includes("application/json") || ct.includes("+json") || ct.includes("text/json"))) {
22343
- const data = await directRes.json();
22344
- const trace2 = {
22345
- trace_id: nanoid9(),
22346
- skill_id: "direct-fetch",
22347
- endpoint_id: "direct-fetch",
22348
- started_at: new Date().toISOString(),
22349
- completed_at: new Date().toISOString(),
22350
- success: true
22351
- };
22352
- const t = finalize("direct-fetch", data, "direct-fetch", undefined, trace2);
22353
- console.log(`[direct-fetch] ${context.url} returned JSON directly — skipping browser`);
22354
- return {
22355
- result: data,
22356
- trace: trace2,
22357
- source: "direct-fetch",
22358
- skill: undefined,
22359
- timing: t
22360
- };
22392
+ const ctSaysJson = ct.includes("application/json") || ct.includes("+json") || ct.includes("text/json");
22393
+ if (directRes.ok) {
22394
+ let data = undefined;
22395
+ if (ctSaysJson) {
22396
+ data = await directRes.json();
22397
+ } else {
22398
+ const bodyText = await directRes.text();
22399
+ if (bodyText.length < 2000000) {
22400
+ const trimmed = bodyText.trimStart();
22401
+ if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
22402
+ try {
22403
+ const parsed = JSON.parse(bodyText);
22404
+ if (parsed !== null && typeof parsed === "object") {
22405
+ data = parsed;
22406
+ console.log(`[direct-fetch] ${context.url} body-sniff hit: ct="${ct}" but body parses as JSON`);
22407
+ }
22408
+ } catch {}
22409
+ }
22410
+ }
22411
+ }
22412
+ if (data !== undefined) {
22413
+ const trace2 = {
22414
+ trace_id: nanoid9(),
22415
+ skill_id: "direct-fetch",
22416
+ endpoint_id: "direct-fetch",
22417
+ started_at: new Date().toISOString(),
22418
+ completed_at: new Date().toISOString(),
22419
+ success: true
22420
+ };
22421
+ const t = finalize("direct-fetch", data, "direct-fetch", undefined, trace2);
22422
+ console.log(`[direct-fetch] ${context.url} returned JSON directly — skipping browser`);
22423
+ return {
22424
+ result: data,
22425
+ trace: trace2,
22426
+ source: "direct-fetch",
22427
+ skill: undefined,
22428
+ timing: t
22429
+ };
22430
+ }
22361
22431
  }
22362
22432
  } catch (err) {
22363
22433
  const msg = err instanceof Error ? err.message : String(err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unbrowse",
3
- "version": "3.7.1",
3
+ "version": "3.8.0-preview.1",
4
4
  "description": "Reverse-engineer any website into reusable API skills. Zero-dep single binary with embedded browser engine.",
5
5
  "type": "module",
6
6
  "bin": {