unbrowse 3.2.0 → 3.2.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.2.0", BUILD_GIT_SHA = "c3fc3f822751", BUILD_CODE_HASH = "1488fc1d92b7", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy4yLjAiLCJnaXRfc2hhIjoiYzNmYzNmODIyNzUxIiwiY29kZV9oYXNoIjoiMTQ4OGZjMWQ5MmI3IiwidHJhY2VfdmVyc2lvbiI6IjE0ODhmYzFkOTJiN0BjM2ZjM2Y4MjI3NTEiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTA2VDA1OjA2OjAxLjIwMFoifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "xCBEHEB2UsniVYLfzuTpoXlcomZHL2pXht-7Ii1e7mM", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
34
+ var BUILD_RELEASE_VERSION = "3.2.1", BUILD_GIT_SHA = "150cce0d751e", BUILD_CODE_HASH = "1488fc1d92b7", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy4yLjEiLCJnaXRfc2hhIjoiMTUwY2NlMGQ3NTFlIiwiY29kZV9oYXNoIjoiMTQ4OGZjMWQ5MmI3IiwidHJhY2VfdmVyc2lvbiI6IjE0ODhmYzFkOTJiN0AxNTBjY2UwZDc1MWUiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTA2VDA3OjM0OjU3LjQ1NFoifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "2iiYVQS4ow2XkpkyCm072lmrjIIGvkAPjkO1s_LI_Do", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
35
35
 
36
36
  // ../../src/version.ts
37
37
  import { createHash } from "crypto";
@@ -802,7 +802,6 @@ var init_token_sources = () => {};
802
802
  // ../../src/execution/token-resolver.ts
803
803
  var init_token_resolver = __esm(() => {
804
804
  init_token_sources();
805
- init_client2();
806
805
  });
807
806
 
808
807
  // ../../src/vault/index.ts
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.2.0";
229
- var BUILD_GIT_SHA = "c3fc3f822751";
228
+ var BUILD_RELEASE_VERSION = "3.2.1";
229
+ var BUILD_GIT_SHA = "150cce0d751e";
230
230
  var BUILD_CODE_HASH = "1488fc1d92b7";
231
- var BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy4yLjAiLCJnaXRfc2hhIjoiYzNmYzNmODIyNzUxIiwiY29kZV9oYXNoIjoiMTQ4OGZjMWQ5MmI3IiwidHJhY2VfdmVyc2lvbiI6IjE0ODhmYzFkOTJiN0BjM2ZjM2Y4MjI3NTEiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTA2VDA1OjA2OjAxLjIwMFoifQ";
232
- var BUILD_RELEASE_MANIFEST_SIGNATURE = "xCBEHEB2UsniVYLfzuTpoXlcomZHL2pXht-7Ii1e7mM";
231
+ var BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy4yLjEiLCJnaXRfc2hhIjoiMTUwY2NlMGQ3NTFlIiwiY29kZV9oYXNoIjoiMTQ4OGZjMWQ5MmI3IiwidHJhY2VfdmVyc2lvbiI6IjE0ODhmYzFkOTJiN0AxNTBjY2UwZDc1MWUiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTA2VDA3OjM0OjU3LjQ1NFoifQ";
232
+ var BUILD_RELEASE_MANIFEST_SIGNATURE = "2iiYVQS4ow2XkpkyCm072lmrjIIGvkAPjkO1s_LI_Do";
233
233
  var BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
234
234
 
235
235
  // ../../src/version.ts
package/dist/server.js CHANGED
@@ -76,6 +76,88 @@ function getPackageRoot(metaUrl) {
76
76
  var init_paths = () => {};
77
77
 
78
78
  // ../../src/kuri/client.ts
79
+ var exports_client = {};
80
+ __export(exports_client, {
81
+ waitForSelector: () => waitForSelector,
82
+ waitForLoad: () => waitForLoad,
83
+ waitForCloudflare: () => waitForCloudflare,
84
+ stop: () => stop,
85
+ start: () => start,
86
+ snapshot: () => snapshot,
87
+ shouldReuseManagedChrome: () => shouldReuseManagedChrome,
88
+ setViewport: () => setViewport,
89
+ setUserAgent: () => setUserAgent,
90
+ setHeaders: () => setHeaders,
91
+ setCredentials: () => setCredentials,
92
+ setCookies: () => setCookies,
93
+ setCookie: () => setCookie,
94
+ setCdpPortForTests: () => setCdpPortForTests,
95
+ sessionSave: () => sessionSave,
96
+ sessionLoad: () => sessionLoad,
97
+ sessionList: () => sessionList,
98
+ select: () => select,
99
+ scrollIntoView: () => scrollIntoView,
100
+ scroll: () => scroll,
101
+ scriptInject: () => scriptInject,
102
+ screenshot: () => screenshot,
103
+ reuseHealthyBrokerIfPossible: () => reuseHealthyBrokerIfPossible,
104
+ resolveKuriPort: () => resolveKuriPort,
105
+ resolveKuriLaunchConfig: () => resolveKuriLaunchConfig,
106
+ reload: () => reload,
107
+ press: () => press,
108
+ newTab: () => newTab,
109
+ networkEnable: () => networkEnable,
110
+ navigate: () => navigate,
111
+ keyboardType: () => keyboardType,
112
+ keyboardInsertText: () => keyboardInsertText,
113
+ keyUp: () => keyUp,
114
+ keyDown: () => keyDown,
115
+ isReady: () => isReady,
116
+ interceptStart: () => interceptStart,
117
+ health: () => health,
118
+ hasCloudflareChallenge: () => hasCloudflareChallenge,
119
+ harStop: () => harStop,
120
+ harStart: () => harStart,
121
+ goForward: () => goForward,
122
+ goBack: () => goBack,
123
+ getText: () => getText,
124
+ getPort: () => getPort,
125
+ getPerfLcp: () => getPerfLcp,
126
+ getPageHtml: () => getPageHtml,
127
+ getNetworkEvents: () => getNetworkEvents,
128
+ getMarkdown: () => getMarkdown,
129
+ getLinks: () => getLinks,
130
+ getKuriSourceCandidates: () => getKuriSourceCandidates,
131
+ getKuriErrorMessage: () => getKuriErrorMessage,
132
+ getKuriClient: () => getKuriClient,
133
+ getKuriBinaryCandidates: () => getKuriBinaryCandidates,
134
+ getErrors: () => getErrors,
135
+ getDefaultTab: () => getDefaultTab,
136
+ getCurrentUrl: () => getCurrentUrl,
137
+ getCookies: () => getCookies,
138
+ getConsole: () => getConsole,
139
+ getCdpPort: () => getCdpPort,
140
+ findText: () => findText,
141
+ findKuriBinary: () => findKuriBinary,
142
+ fill: () => fill,
143
+ extractLoadPluginsFromHtml: () => extractLoadPluginsFromHtml,
144
+ extractLoadPlugins: () => extractLoadPlugins,
145
+ executeInPageFetch: () => executeInPageFetch,
146
+ evaluate: () => evaluate,
147
+ drag: () => drag,
148
+ domQuery: () => domQuery,
149
+ domHtml: () => domHtml,
150
+ domAttributes: () => domAttributes,
151
+ discoverTabs: () => discoverTabs,
152
+ closeTab: () => closeTab,
153
+ click: () => click,
154
+ bestEffortRehydratePlugins: () => bestEffortRehydratePlugins,
155
+ authProfileSave: () => authProfileSave,
156
+ authProfileLoad: () => authProfileLoad,
157
+ authProfileList: () => authProfileList,
158
+ authProfileDelete: () => authProfileDelete,
159
+ action: () => action
160
+ });
79
161
  import { execFileSync, spawn } from "node:child_process";
80
162
  import { existsSync as existsSync2 } from "node:fs";
81
163
  import net from "node:net";
@@ -977,6 +1059,19 @@ async function getPageHtml(tabId, state = defaultBrokerState) {
977
1059
  const result = await evaluate(tabId, "document.documentElement.outerHTML", state);
978
1060
  return String(result ?? "");
979
1061
  }
1062
+ function extractLoadPlugins(value) {
1063
+ if (typeof value !== "string")
1064
+ return [];
1065
+ return Array.from(new Set(value.split(/[\s,;]+/).map((part) => part.trim()).filter(Boolean)));
1066
+ }
1067
+ function extractLoadPluginsFromHtml(html) {
1068
+ const modules = [];
1069
+ const pattern = /data-load-plugins=(["'])(.*?)\1/gi;
1070
+ for (const match of html.matchAll(pattern)) {
1071
+ modules.push(...extractLoadPlugins(match[2]));
1072
+ }
1073
+ return Array.from(new Set(modules));
1074
+ }
980
1075
  async function bestEffortRehydratePlugins(tabId, state = defaultBrokerState) {
981
1076
  const result = await evaluate(tabId, `(async function() {
982
1077
  function splitPlugins(value) {
@@ -1118,6 +1213,9 @@ function getPort(state = defaultBrokerState) {
1118
1213
  function getCdpPort() {
1119
1214
  return kuriCdpPort;
1120
1215
  }
1216
+ function setCdpPortForTests(port) {
1217
+ kuriCdpPort = port;
1218
+ }
1121
1219
  function isReady(state = defaultBrokerState) {
1122
1220
  return state.ready;
1123
1221
  }
@@ -6380,7 +6478,7 @@ var init_capture = __esm(() => {
6380
6478
  });
6381
6479
 
6382
6480
  // ../../src/build-info.generated.ts
6383
- var BUILD_RELEASE_VERSION = "3.2.0", BUILD_GIT_SHA = "c3fc3f822751", BUILD_CODE_HASH = "1488fc1d92b7", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy4yLjAiLCJnaXRfc2hhIjoiYzNmYzNmODIyNzUxIiwiY29kZV9oYXNoIjoiMTQ4OGZjMWQ5MmI3IiwidHJhY2VfdmVyc2lvbiI6IjE0ODhmYzFkOTJiN0BjM2ZjM2Y4MjI3NTEiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTA2VDA1OjA2OjAxLjIwMFoifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "xCBEHEB2UsniVYLfzuTpoXlcomZHL2pXht-7Ii1e7mM", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
6481
+ var BUILD_RELEASE_VERSION = "3.2.1", BUILD_GIT_SHA = "150cce0d751e", BUILD_CODE_HASH = "1488fc1d92b7", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy4yLjEiLCJnaXRfc2hhIjoiMTUwY2NlMGQ3NTFlIiwiY29kZV9oYXNoIjoiMTQ4OGZjMWQ5MmI3IiwidHJhY2VfdmVyc2lvbiI6IjE0ODhmYzFkOTJiN0AxNTBjY2UwZDc1MWUiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTA2VDA3OjM0OjU3LjQ1NFoifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "2iiYVQS4ow2XkpkyCm072lmrjIIGvkAPjkO1s_LI_Do", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
6384
6482
 
6385
6483
  // ../../src/version.ts
6386
6484
  import { createHash } from "crypto";
@@ -8818,121 +8916,206 @@ async function resolveAuthTokens(endpoint, cookies, existingAuthHeaders) {
8818
8916
  const triggerUrl = endpoint.trigger_url;
8819
8917
  if (!triggerUrl)
8820
8918
  return {};
8821
- const headerBindings = bindings.filter((b) => b.param_location === "header");
8919
+ const headerBindings = bindings.filter((b) => b.param_location === "header" && !existingAuthHeaders[b.param_name]);
8822
8920
  if (headerBindings.length === 0)
8823
8921
  return {};
8824
8922
  const resolved = {};
8825
- try {
8826
- const tabId = await openResolverTab(triggerUrl, cookies);
8827
- if (!tabId)
8828
- return {};
8829
- try {
8830
- await waitForLoad2(tabId);
8831
- const html = await getPageHtml(tabId).catch(() => "");
8832
- if (typeof html !== "string" || !html.startsWith("<")) {
8833
- return {};
8834
- }
8835
- for (const binding of headerBindings) {
8836
- let value = await resolveBinding(binding, html, cookies);
8837
- if (!value && binding.sources.some((s) => s.kind === "js-bundle")) {
8838
- value = await scanAllScriptResources(tabId, binding);
8839
- }
8840
- if (value) {
8841
- resolved[binding.param_name] = binding.param_name.toLowerCase() === "authorization" ? value.startsWith("Bearer ") ? value : `Bearer ${value}` : value;
8923
+ for (const binding of headerBindings) {
8924
+ const cookieSources = binding.sources.filter((s) => s.kind === "cookie");
8925
+ if (cookieSources.length === 0)
8926
+ continue;
8927
+ for (const source of cookieSources) {
8928
+ const names = source.cookie_names ?? [];
8929
+ for (const name of names) {
8930
+ const cookie = cookies.find((c) => c.name === name);
8931
+ if (cookie?.value && cookie.value.length >= 8) {
8932
+ resolved[binding.param_name] = cookie.value;
8933
+ break;
8842
8934
  }
8843
8935
  }
8844
- } finally {
8845
- await closeTab(tabId).catch(() => {});
8936
+ if (resolved[binding.param_name])
8937
+ break;
8846
8938
  }
8847
- } catch {}
8939
+ }
8940
+ const remaining = headerBindings.filter((b) => !resolved[b.param_name]);
8941
+ if (remaining.length === 0)
8942
+ return formatHeaders(resolved);
8943
+ if (!hasResolvableSources(remaining))
8944
+ return formatHeaders(resolved);
8945
+ const html = await fetchHtml(triggerUrl, cookies);
8946
+ if (html) {
8947
+ const fromHtml = await resolveFromHtml(remaining, html);
8948
+ Object.assign(resolved, fromHtml);
8949
+ const stillMissing = remaining.filter((b) => !resolved[b.param_name]);
8950
+ if (stillMissing.length === 0)
8951
+ return formatHeaders(resolved);
8952
+ if (Object.keys(fromHtml).length > 0 && hasHtmlResolvableSources(stillMissing)) {
8953
+ const browserHtml = await fetchHtmlViaBrowser(triggerUrl, cookies);
8954
+ if (browserHtml) {
8955
+ Object.assign(resolved, await resolveFromHtml(stillMissing, browserHtml));
8956
+ }
8957
+ }
8958
+ return formatHeaders(resolved);
8959
+ }
8960
+ if (hasHtmlResolvableSources(remaining)) {
8961
+ const browserHtml = await fetchHtmlViaBrowser(triggerUrl, cookies);
8962
+ if (browserHtml) {
8963
+ Object.assign(resolved, await resolveFromHtml(remaining, browserHtml));
8964
+ }
8965
+ }
8966
+ return formatHeaders(resolved);
8967
+ }
8968
+ function hasResolvableSources(bindings) {
8969
+ for (const b of bindings) {
8970
+ for (const s of b.sources) {
8971
+ if (s.kind === "html-meta" || s.kind === "html-inline-script")
8972
+ return true;
8973
+ if (s.kind === "js-bundle" && s.bundle_url_pattern && s.bundle_regex)
8974
+ return true;
8975
+ }
8976
+ }
8977
+ return false;
8978
+ }
8979
+ function hasHtmlResolvableSources(bindings) {
8980
+ for (const b of bindings) {
8981
+ for (const s of b.sources) {
8982
+ if (s.kind === "html-meta" || s.kind === "html-inline-script")
8983
+ return true;
8984
+ }
8985
+ }
8986
+ return false;
8987
+ }
8988
+ function formatHeaders(raw) {
8989
+ const out = {};
8990
+ for (const [k, v] of Object.entries(raw)) {
8991
+ if (k.toLowerCase() === "authorization" && !v.startsWith("Bearer ")) {
8992
+ out[k] = `Bearer ${v}`;
8993
+ } else {
8994
+ out[k] = v;
8995
+ }
8996
+ }
8997
+ return out;
8998
+ }
8999
+ async function resolveFromHtml(bindings, html) {
9000
+ const resolved = {};
9001
+ for (const binding of bindings) {
9002
+ const value = await resolveBinding(binding, html);
9003
+ if (value)
9004
+ resolved[binding.param_name] = value;
9005
+ }
8848
9006
  return resolved;
8849
9007
  }
8850
- async function resolveBinding(binding, html, cookies) {
9008
+ async function resolveBinding(binding, html) {
8851
9009
  for (const source of binding.sources) {
8852
9010
  let value;
8853
- if (source.kind === "cookie" && source.cookie_names?.length) {
8854
- for (const name of source.cookie_names) {
8855
- const cookie = cookies.find((c) => c.name === name);
8856
- if (cookie?.value) {
8857
- value = cookie.value;
8858
- break;
8859
- }
8860
- }
8861
- } else if (source.kind === "html-meta" || source.kind === "html-inline-script") {
9011
+ if (source.kind === "html-meta" || source.kind === "html-inline-script") {
8862
9012
  value = extractTokenFromHtml(source, html);
8863
- } else if (source.kind === "js-bundle" && source.bundle_url_pattern) {
8864
- try {
8865
- const resp = await fetch(source.bundle_url_pattern);
8866
- if (resp.ok) {
8867
- const body = await resp.text();
8868
- value = extractTokenFromBundle(source, body);
8869
- }
8870
- } catch {}
9013
+ } else if (source.kind === "js-bundle" && source.bundle_url_pattern && source.bundle_regex) {
9014
+ value = await resolveJsBundle(source, html);
8871
9015
  }
8872
9016
  if (value && value.length >= 8)
8873
9017
  return value;
8874
9018
  }
8875
9019
  return;
8876
9020
  }
8877
- async function openResolverTab(url, cookies) {
9021
+ async function resolveJsBundle(source, html) {
9022
+ const pattern = source.bundle_url_pattern;
9023
+ const scriptSrcRe = /<script[^>]+src=["']([^"']+)["']/gi;
9024
+ let match;
9025
+ while ((match = scriptSrcRe.exec(html)) !== null) {
9026
+ const src = match[1];
9027
+ if (!src.includes(pattern))
9028
+ continue;
9029
+ try {
9030
+ const url = src.startsWith("http") ? src : `https:${src}`;
9031
+ const controller = new AbortController;
9032
+ const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
9033
+ const res = await fetch(url, {
9034
+ headers: { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" },
9035
+ signal: controller.signal
9036
+ });
9037
+ clearTimeout(timeout);
9038
+ if (!res.ok)
9039
+ continue;
9040
+ const bundleContent = await res.text();
9041
+ const extracted = extractTokenFromBundle(source, bundleContent);
9042
+ if (extracted && extracted.length >= 8)
9043
+ return extracted;
9044
+ } catch {}
9045
+ }
9046
+ return;
9047
+ }
9048
+ async function fetchHtml(url, cookies) {
8878
9049
  try {
8879
- const tab = await newTab(url);
8880
- const tabId = typeof tab === "string" ? tab : tab?.tab_id;
8881
- if (!tabId)
8882
- return;
8883
- if (cookies.length > 0) {
8884
- for (const c of cookies) {
8885
- await setCookie(tabId, c.name, c.value, c.domain).catch(() => {});
8886
- }
8887
- await navigate(tabId, url).catch(() => {});
8888
- }
8889
- return tabId;
9050
+ const cookieHeader = cookies.map((c) => `${c.name}=${c.value}`).join("; ");
9051
+ const controller = new AbortController;
9052
+ const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
9053
+ const res = await fetch(url, {
9054
+ headers: {
9055
+ Cookie: cookieHeader,
9056
+ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
9057
+ Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
9058
+ "Accept-Language": "en-US,en;q=0.9"
9059
+ },
9060
+ redirect: "follow",
9061
+ signal: controller.signal
9062
+ });
9063
+ clearTimeout(timeout);
9064
+ if (!res.ok)
9065
+ return null;
9066
+ const ct = res.headers.get("content-type") ?? "";
9067
+ if (!ct.includes("text/html") && !ct.includes("text/plain") && !ct.includes("application/xhtml"))
9068
+ return null;
9069
+ const html = await res.text();
9070
+ if (!html || html.length < 200 || !html.includes("<"))
9071
+ return null;
9072
+ return html;
8890
9073
  } catch {
8891
- return;
9074
+ return null;
8892
9075
  }
8893
9076
  }
8894
- async function waitForLoad2(tabId) {
8895
- const start2 = Date.now();
8896
- while (Date.now() - start2 < RESOLVE_TIMEOUT_MS) {
8897
- try {
8898
- const state = await evaluate(tabId, "document.readyState");
8899
- if (state === "complete" || state === "interactive")
8900
- return;
8901
- } catch {}
8902
- await new Promise((r) => setTimeout(r, 500));
9077
+ async function fetchHtmlViaBrowser(url, cookies) {
9078
+ let kuri;
9079
+ try {
9080
+ kuri = await Promise.resolve().then(() => (init_client(), exports_client));
9081
+ } catch {
9082
+ return null;
8903
9083
  }
8904
- }
8905
- async function scanAllScriptResources(tabId, binding) {
9084
+ let tabId;
8906
9085
  try {
8907
- const raw = await evaluate(tabId, `
8908
- JSON.stringify(
8909
- performance.getEntriesByType('resource')
8910
- .filter(function(e) { return e.initiatorType === 'script'; })
8911
- .map(function(e) { return e.name; })
8912
- )
8913
- `);
8914
- if (typeof raw !== "string" || !raw.startsWith("["))
8915
- return;
8916
- const urls = JSON.parse(raw);
8917
- const tokenPattern = /AAAAAAAAAAAAAAAAAAA[A-Za-z0-9+/=_%-]{20,}/;
8918
- for (const url of urls) {
9086
+ const tab = await kuri.newTab(url);
9087
+ tabId = typeof tab === "string" ? tab : tab?.tab_id;
9088
+ if (!tabId)
9089
+ return null;
9090
+ if (cookies.length > 0) {
9091
+ for (const c of cookies) {
9092
+ await kuri.setCookie(tabId, c.name, c.value, c.domain).catch(() => {});
9093
+ }
9094
+ await kuri.navigate(tabId, url).catch(() => {});
9095
+ }
9096
+ const start2 = Date.now();
9097
+ while (Date.now() - start2 < 12000) {
8919
9098
  try {
8920
- const resp = await fetch(url);
8921
- if (!resp.ok)
8922
- continue;
8923
- const body = await resp.text();
8924
- const m = body.match(tokenPattern);
8925
- if (m && m[0].length >= 20)
8926
- return m[0];
9099
+ const state = await kuri.evaluate(tabId, "document.readyState");
9100
+ if (state === "complete" || state === "interactive")
9101
+ break;
8927
9102
  } catch {}
9103
+ await new Promise((r) => setTimeout(r, 500));
8928
9104
  }
8929
- } catch {}
8930
- return;
9105
+ const html = await kuri.getPageHtml(tabId).catch(() => "");
9106
+ if (typeof html !== "string" || !html.startsWith("<"))
9107
+ return null;
9108
+ return html;
9109
+ } catch {
9110
+ return null;
9111
+ } finally {
9112
+ if (tabId)
9113
+ await kuri.closeTab(tabId).catch(() => {});
9114
+ }
8931
9115
  }
8932
- var RESOLVE_TIMEOUT_MS = 12000;
9116
+ var FETCH_TIMEOUT_MS = 8000;
8933
9117
  var init_token_resolver = __esm(() => {
8934
9118
  init_token_sources();
8935
- init_client();
8936
9119
  });
8937
9120
 
8938
9121
  // ../../src/vault/index.ts
@@ -20592,7 +20775,7 @@ async function resolveAndExecute(intent, params = {}, context, projection, optio
20592
20775
  }
20593
20776
  } catch {}
20594
20777
  }
20595
- if (context?.url && !forceCapture) {
20778
+ if (process.env.UNBROWSE_LOCAL_ONLY === "1" && !forceCapture) {
20596
20779
  return buildNoCachedMatch();
20597
20780
  }
20598
20781
  if (!context?.url) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unbrowse",
3
- "version": "3.2.0",
3
+ "version": "3.2.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": {
Binary file
Binary file
Binary file
Binary file
@@ -2,24 +2,27 @@
2
2
  "repo_url": "https://github.com/justrach/kuri.git",
3
3
  "branch": "adding-extensions",
4
4
  "source_sha": "eadfaa5f921f7152e1762aed5ed64b3a4fbefbf3",
5
- "built_at": "2026-04-06T05:01:20.543Z",
5
+ "built_at": "2026-04-05T06:43:57.212Z",
6
6
  "binaries": {
7
7
  "darwin-arm64": {
8
8
  "zig_target": "aarch64-macos",
9
- "sha256": "1796501e393403016723c6b69266b834e2db04ba2559f51c84c957bd85c3927b",
10
- "source": "prebuilt"
9
+ "sha256": "1553633e722d18059dedffa8a52d55ed6c052e4961fd2753ee0b62be60b241bf"
11
10
  },
12
11
  "darwin-x64": {
13
12
  "zig_target": "x86_64-macos",
14
- "sha256": "f9adbebad3b17c10fc359b8125a33eda6890ec728cb2b6c625b36b895ef7c97f"
13
+ "sha256": "b5eb07e631c6ddad64019c8d0c86c32cb76a74ff0791ac5611a3aa3550767ec8"
15
14
  },
16
15
  "linux-arm64": {
17
16
  "zig_target": "aarch64-linux",
18
- "sha256": "30d1da652d589e5dffa4520615f958db3acf063bd831da9662c97afd50969699"
17
+ "sha256": "ea88a26f7b335d5842b0c1d83bfa4066bed0a119284560f6bd3833f1d240cce2"
19
18
  },
20
19
  "linux-x64": {
21
20
  "zig_target": "x86_64-linux",
22
- "sha256": "90a8d60715a5c1723b7dae98d90a565b92a781b16ab8721fd546a26f9d86f39f"
21
+ "sha256": "175a7c59e458e952a26974f0fb5c2ce374e56f2c4c352903b481b5aa5a16978f"
22
+ },
23
+ "win-x64": {
24
+ "zig_target": "x86_64-windows",
25
+ "sha256": "176291ad9827a183ba7322ddb56cc1fa5edc7c214a264ecdf8a1d5d18366d686"
23
26
  }
24
27
  }
25
28
  }
Binary file