unbrowse 3.1.0-experiments.a2cf008 → 3.1.0-experiments.acc0c3e
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 +14 -4
- package/dist/mcp.js +5 -5
- package/package.json +1 -1
- package/runtime-src/api/browse-index.ts +4 -0
- package/runtime-src/build-info.generated.ts +4 -4
- package/runtime-src/client/index.ts +15 -3
- package/runtime-src/execution/index.ts +3 -2
- package/runtime-src/execution/token-resolver.ts +40 -1
- package/runtime-src/reverse-engineer/token-sources.ts +1 -1
- package/vendor/kuri/darwin-arm64/kuri +0 -0
- package/vendor/kuri/darwin-x64/kuri +0 -0
- package/vendor/kuri/linux-arm64/kuri +0 -0
- package/vendor/kuri/linux-x64/kuri +0 -0
- package/vendor/kuri/manifest.json +7 -10
- package/vendor/kuri/win-x64/kuri.exe +0 -0
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.1.0-experiments.
|
|
34
|
+
var BUILD_RELEASE_VERSION = "3.1.0-experiments.acc0c3e", BUILD_GIT_SHA = "acc0c3e1f8c5", BUILD_CODE_HASH = "1488fc1d92b7", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy4xLjAtZXhwZXJpbWVudHMuYWNjMGMzZSIsImdpdF9zaGEiOiJhY2MwYzNlMWY4YzUiLCJjb2RlX2hhc2giOiIxNDg4ZmMxZDkyYjciLCJ0cmFjZV92ZXJzaW9uIjoiMTQ4OGZjMWQ5MmI3QGFjYzBjM2UxZjhjNSIsImlzc3VlZF9hdCI6IjIwMjYtMDQtMDZUMDI6MzI6NTMuOTQxWiJ9", BUILD_RELEASE_MANIFEST_SIGNATURE = "ZqdsNG9DQl3Sx4n94HXYdmjYsiExN3BXql7Z-yRx7wE", BUILD_DEFAULT_BACKEND_URL = "https://unbrowse-backend-experiments.lewis-6d8.workers.dev";
|
|
35
35
|
|
|
36
36
|
// ../../src/version.ts
|
|
37
37
|
import { createHash } from "crypto";
|
|
@@ -1369,7 +1369,7 @@ init_wallet();
|
|
|
1369
1369
|
init_telemetry_attribution();
|
|
1370
1370
|
import { readFileSync as readFileSync3, writeFileSync, existsSync as existsSync4, mkdirSync, readdirSync as readdirSync2 } from "fs";
|
|
1371
1371
|
import { join as join4 } from "path";
|
|
1372
|
-
import { homedir as homedir3, hostname } from "os";
|
|
1372
|
+
import { homedir as homedir3, hostname, release as osRelease } from "os";
|
|
1373
1373
|
import { randomBytes, createHash as createHash2 } from "crypto";
|
|
1374
1374
|
import { createInterface } from "readline";
|
|
1375
1375
|
var API_URL = process.env.UNBROWSE_BACKEND_URL || DEFAULT_BACKEND_URL;
|
|
@@ -1562,9 +1562,19 @@ async function recordInstallTelemetryEvent(source, options) {
|
|
|
1562
1562
|
skill_version: options?.skillVersion,
|
|
1563
1563
|
status: options?.status ?? "installed",
|
|
1564
1564
|
created_at: createdAt,
|
|
1565
|
-
properties: mergeTelemetryProperties(options?.properties, getTelemetryAttribution())
|
|
1565
|
+
properties: mergeTelemetryProperties({ ...getRuntimeContext(), ...options?.properties }, getTelemetryAttribution())
|
|
1566
1566
|
});
|
|
1567
1567
|
}
|
|
1568
|
+
function getRuntimeContext() {
|
|
1569
|
+
return {
|
|
1570
|
+
cli_version: PACKAGE_VERSION,
|
|
1571
|
+
code_hash: CODE_HASH,
|
|
1572
|
+
node_version: process.version,
|
|
1573
|
+
platform: process.platform,
|
|
1574
|
+
arch: process.arch,
|
|
1575
|
+
os_release: osRelease()
|
|
1576
|
+
};
|
|
1577
|
+
}
|
|
1568
1578
|
async function recordFunnelTelemetryEvent(name, options) {
|
|
1569
1579
|
const createdAt = options?.createdAt ?? new Date().toISOString();
|
|
1570
1580
|
const landingToken = getLandingToken();
|
|
@@ -1576,7 +1586,7 @@ async function recordFunnelTelemetryEvent(name, options) {
|
|
|
1576
1586
|
source: options?.source ?? "cli",
|
|
1577
1587
|
host_type: options?.hostType ?? detectTelemetryHostType(),
|
|
1578
1588
|
created_at: createdAt,
|
|
1579
|
-
properties: mergeTelemetryProperties(options?.properties, getTelemetryAttribution())
|
|
1589
|
+
properties: mergeTelemetryProperties({ ...getRuntimeContext(), ...options?.properties }, getTelemetryAttribution())
|
|
1580
1590
|
});
|
|
1581
1591
|
}
|
|
1582
1592
|
var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/i;
|
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.1.0-experiments.
|
|
229
|
-
var BUILD_GIT_SHA = "
|
|
228
|
+
var BUILD_RELEASE_VERSION = "3.1.0-experiments.acc0c3e";
|
|
229
|
+
var BUILD_GIT_SHA = "acc0c3e1f8c5";
|
|
230
230
|
var BUILD_CODE_HASH = "1488fc1d92b7";
|
|
231
|
-
var BUILD_RELEASE_MANIFEST_BASE64 = "
|
|
232
|
-
var BUILD_RELEASE_MANIFEST_SIGNATURE = "
|
|
231
|
+
var BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy4xLjAtZXhwZXJpbWVudHMuYWNjMGMzZSIsImdpdF9zaGEiOiJhY2MwYzNlMWY4YzUiLCJjb2RlX2hhc2giOiIxNDg4ZmMxZDkyYjciLCJ0cmFjZV92ZXJzaW9uIjoiMTQ4OGZjMWQ5MmI3QGFjYzBjM2UxZjhjNSIsImlzc3VlZF9hdCI6IjIwMjYtMDQtMDZUMDI6MzI6NTMuOTQxWiJ9";
|
|
232
|
+
var BUILD_RELEASE_MANIFEST_SIGNATURE = "ZqdsNG9DQl3Sx4n94HXYdmjYsiExN3BXql7Z-yRx7wE";
|
|
233
233
|
var BUILD_DEFAULT_BACKEND_URL = "https://unbrowse-backend-experiments.lewis-6d8.workers.dev";
|
|
234
234
|
|
|
235
235
|
// ../../src/version.ts
|
|
@@ -743,7 +743,7 @@ function readImpactSummary() {
|
|
|
743
743
|
// ../../src/client/index.ts
|
|
744
744
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync6, mkdirSync as mkdirSync4, readdirSync as readdirSync3 } from "fs";
|
|
745
745
|
import { join as join5 } from "path";
|
|
746
|
-
import { homedir as homedir4, hostname } from "os";
|
|
746
|
+
import { homedir as homedir4, hostname, release as osRelease } from "os";
|
|
747
747
|
|
|
748
748
|
// ../../src/payments/cascade.ts
|
|
749
749
|
import bs58 from "bs58";
|
package/package.json
CHANGED
|
@@ -169,6 +169,10 @@ export async function cacheBrowseRequests(params: {
|
|
|
169
169
|
// so serverFetch can replay them. Use registrable domain for vault key
|
|
170
170
|
// so ads.x.com and ads-api.x.com share the same session.
|
|
171
171
|
const capturedAuthHeaders = extractAuthHeaders(requests);
|
|
172
|
+
// Filter out [REDACTED] placeholders from cookie-inferred auth headers
|
|
173
|
+
for (const [k, v] of Object.entries(capturedAuthHeaders)) {
|
|
174
|
+
if (v === "[REDACTED]") delete capturedAuthHeaders[k];
|
|
175
|
+
}
|
|
172
176
|
if (Object.keys(capturedAuthHeaders).length > 0) {
|
|
173
177
|
const sessionKey = `${getRegistrableDomain(domain)}-session`;
|
|
174
178
|
await storeCredential(sessionKey, JSON.stringify({ headers: capturedAuthHeaders })).catch(() => {});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export const BUILD_RELEASE_VERSION = "3.1.0-experiments.
|
|
2
|
-
export const BUILD_GIT_SHA = "
|
|
1
|
+
export const BUILD_RELEASE_VERSION = "3.1.0-experiments.acc0c3e";
|
|
2
|
+
export const BUILD_GIT_SHA = "acc0c3e1f8c5";
|
|
3
3
|
export const BUILD_CODE_HASH = "1488fc1d92b7";
|
|
4
|
-
export const BUILD_RELEASE_MANIFEST_BASE64 = "
|
|
5
|
-
export const BUILD_RELEASE_MANIFEST_SIGNATURE = "
|
|
4
|
+
export const BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy4xLjAtZXhwZXJpbWVudHMuYWNjMGMzZSIsImdpdF9zaGEiOiJhY2MwYzNlMWY4YzUiLCJjb2RlX2hhc2giOiIxNDg4ZmMxZDkyYjciLCJ0cmFjZV92ZXJzaW9uIjoiMTQ4OGZjMWQ5MmI3QGFjYzBjM2UxZjhjNSIsImlzc3VlZF9hdCI6IjIwMjYtMDQtMDZUMDI6MzI6NTMuOTQxWiJ9";
|
|
5
|
+
export const BUILD_RELEASE_MANIFEST_SIGNATURE = "ZqdsNG9DQl3Sx4n94HXYdmjYsiExN3BXql7Z-yRx7wE";
|
|
6
6
|
export const BUILD_DEFAULT_BACKEND_URL = "https://unbrowse-backend-experiments.lewis-6d8.workers.dev";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync } from "fs";
|
|
2
2
|
import { join } from "path";
|
|
3
|
-
import { homedir, hostname } from "os";
|
|
3
|
+
import { homedir, hostname, release as osRelease } from "os";
|
|
4
4
|
import { randomBytes, createHash } from "crypto";
|
|
5
5
|
import { createInterface } from "readline";
|
|
6
6
|
import type {
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
CODE_HASH,
|
|
17
17
|
DEFAULT_BACKEND_URL,
|
|
18
18
|
GIT_SHA,
|
|
19
|
+
PACKAGE_VERSION,
|
|
19
20
|
RELEASE_MANIFEST_BASE64,
|
|
20
21
|
RELEASE_MANIFEST_SIGNATURE,
|
|
21
22
|
TRACE_VERSION,
|
|
@@ -302,10 +303,21 @@ export async function recordInstallTelemetryEvent(
|
|
|
302
303
|
skill_version: options?.skillVersion,
|
|
303
304
|
status: options?.status ?? "installed",
|
|
304
305
|
created_at: createdAt,
|
|
305
|
-
properties: mergeTelemetryProperties(options?.properties, getTelemetryAttribution()),
|
|
306
|
+
properties: mergeTelemetryProperties({ ...getRuntimeContext(), ...options?.properties }, getTelemetryAttribution()),
|
|
306
307
|
});
|
|
307
308
|
}
|
|
308
309
|
|
|
310
|
+
function getRuntimeContext(): Record<string, unknown> {
|
|
311
|
+
return {
|
|
312
|
+
cli_version: PACKAGE_VERSION,
|
|
313
|
+
code_hash: CODE_HASH,
|
|
314
|
+
node_version: process.version,
|
|
315
|
+
platform: process.platform,
|
|
316
|
+
arch: process.arch,
|
|
317
|
+
os_release: osRelease(),
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
309
321
|
export async function recordFunnelTelemetryEvent(
|
|
310
322
|
name: string,
|
|
311
323
|
options?: {
|
|
@@ -326,7 +338,7 @@ export async function recordFunnelTelemetryEvent(
|
|
|
326
338
|
source: options?.source ?? "cli",
|
|
327
339
|
host_type: options?.hostType ?? detectTelemetryHostType(),
|
|
328
340
|
created_at: createdAt,
|
|
329
|
-
properties: mergeTelemetryProperties(options?.properties, getTelemetryAttribution()),
|
|
341
|
+
properties: mergeTelemetryProperties({ ...getRuntimeContext(), ...options?.properties }, getTelemetryAttribution()),
|
|
330
342
|
});
|
|
331
343
|
}
|
|
332
344
|
|
|
@@ -2022,7 +2022,7 @@ export async function executeEndpoint(
|
|
|
2022
2022
|
try {
|
|
2023
2023
|
const { resolveAuthTokens } = await import("./token-resolver.js");
|
|
2024
2024
|
const resolved = await resolveAuthTokens(endpoint, cookies, authHeaders);
|
|
2025
|
-
log("exec", `token resolver returned ${Object.keys(resolved).length} headers: ${Object.keys(resolved).join(",") || "none"}`);
|
|
2025
|
+
log("exec", `token resolver returned ${Object.keys(resolved).length} headers: ${Object.keys(resolved).join(",") || "none"} auth=${(resolved.authorization || "").substring(0, 40)}`);
|
|
2026
2026
|
Object.assign(authHeaders, resolved);
|
|
2027
2027
|
} catch (e) { log("exec", `token resolver failed: ${e}`); }
|
|
2028
2028
|
}
|
|
@@ -2241,7 +2241,7 @@ export async function executeEndpoint(
|
|
|
2241
2241
|
|
|
2242
2242
|
for (const replayUrl of replayUrls) {
|
|
2243
2243
|
const replayHeaders = buildStructuredReplayHeaders(url, replayUrl, headers);
|
|
2244
|
-
log("exec", `server-fetch: ${endpoint.method} ${replayUrl.substring(0, 80)} csrf=${replayHeaders["x-csrf-token"]?.substring(0, 10)}... cookies=${(replayHeaders["cookie"]?.length ?? 0)}chars`);
|
|
2244
|
+
log("exec", `server-fetch: ${endpoint.method} ${replayUrl.substring(0, 80)} auth=${(replayHeaders["authorization"] || "none").substring(0, 50)} csrf=${replayHeaders["x-csrf-token"]?.substring(0, 10)}... cookies=${(replayHeaders["cookie"]?.length ?? 0)}chars`);
|
|
2245
2245
|
const res = await fetch(replayUrl, {
|
|
2246
2246
|
method: endpoint.method,
|
|
2247
2247
|
headers: replayHeaders,
|
|
@@ -3165,6 +3165,7 @@ export function rankEndpoints(endpoints: EndpointDescriptor[], intent?: string,
|
|
|
3165
3165
|
}
|
|
3166
3166
|
}
|
|
3167
3167
|
score += ep.reliability_score * 5;
|
|
3168
|
+
if (ep.verification_status === "verified") score += 15;
|
|
3168
3169
|
if (ep.method === "WS" && ep.response_schema) score += 3;
|
|
3169
3170
|
|
|
3170
3171
|
// === Domain affinity ===
|
|
@@ -54,7 +54,14 @@ export async function resolveAuthTokens(
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
for (const binding of headerBindings) {
|
|
57
|
-
|
|
57
|
+
let value = await resolveBinding(binding, html, cookies);
|
|
58
|
+
|
|
59
|
+
// If stored sources didn't resolve (e.g. bearer in a different bundle),
|
|
60
|
+
// scan all loaded script resources via Performance API
|
|
61
|
+
if (!value && binding.sources.some((s) => s.kind === "js-bundle")) {
|
|
62
|
+
value = await scanAllScriptResources(tabId, binding);
|
|
63
|
+
}
|
|
64
|
+
|
|
58
65
|
if (value) {
|
|
59
66
|
resolved[binding.param_name] = binding.param_name.toLowerCase() === "authorization"
|
|
60
67
|
? (value.startsWith("Bearer ") ? value : `Bearer ${value}`)
|
|
@@ -133,3 +140,35 @@ async function waitForLoad(tabId: string): Promise<void> {
|
|
|
133
140
|
await new Promise((r) => setTimeout(r, 500));
|
|
134
141
|
}
|
|
135
142
|
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Scan all script resources loaded by the page via Performance API.
|
|
146
|
+
* Fetches each bundle and searches for a token matching the binding pattern.
|
|
147
|
+
* This handles cases where the enrichment captured the wrong bundle URLs.
|
|
148
|
+
*/
|
|
149
|
+
async function scanAllScriptResources(tabId: string, binding: AuthTokenBinding): Promise<string | undefined> {
|
|
150
|
+
try {
|
|
151
|
+
const raw = await kuri.evaluate(tabId, `
|
|
152
|
+
JSON.stringify(
|
|
153
|
+
performance.getEntriesByType('resource')
|
|
154
|
+
.filter(function(e) { return e.initiatorType === 'script'; })
|
|
155
|
+
.map(function(e) { return e.name; })
|
|
156
|
+
)
|
|
157
|
+
`);
|
|
158
|
+
if (typeof raw !== "string" || !raw.startsWith("[")) return undefined;
|
|
159
|
+
const urls: string[] = JSON.parse(raw);
|
|
160
|
+
|
|
161
|
+
const tokenPattern = /AAAAAAAAAAAAAAAAAAA[A-Za-z0-9+/=_%-]{20,}/;
|
|
162
|
+
|
|
163
|
+
for (const url of urls) {
|
|
164
|
+
try {
|
|
165
|
+
const resp = await fetch(url);
|
|
166
|
+
if (!resp.ok) continue;
|
|
167
|
+
const body = await resp.text();
|
|
168
|
+
const m = body.match(tokenPattern);
|
|
169
|
+
if (m && m[0].length >= 20) return m[0];
|
|
170
|
+
} catch { /* fetch failed, try next */ }
|
|
171
|
+
}
|
|
172
|
+
} catch { /* evaluate failed */ }
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
@@ -309,7 +309,7 @@ export function enrichEndpointsWithTokenSources(
|
|
|
309
309
|
sources.push({ kind: "cookie", cookie_names: ["ct0", "csrf_token", "_csrf", "csrftoken", "XSRF-TOKEN"] });
|
|
310
310
|
} else if (lowerName === "authorization") {
|
|
311
311
|
if (html) {
|
|
312
|
-
const scriptSrcRe = /<script[^>]+src=["']([^"']
|
|
312
|
+
const scriptSrcRe = /<script[^>]+src=["']([^"']+)["']/gi;
|
|
313
313
|
let m: RegExpExecArray | null;
|
|
314
314
|
while ((m = scriptSrcRe.exec(html)) !== null) {
|
|
315
315
|
if (/main|app|client|bundle|vendor/i.test(m[1])) {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,28 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"repo_url": "https://github.com/justrach/kuri.git",
|
|
3
3
|
"branch": "adding-extensions",
|
|
4
|
-
"source_sha": "
|
|
5
|
-
"built_at": "2026-04-
|
|
4
|
+
"source_sha": "eadfaa5f921f7152e1762aed5ed64b3a4fbefbf3",
|
|
5
|
+
"built_at": "2026-04-06T02:32:53.993Z",
|
|
6
6
|
"binaries": {
|
|
7
7
|
"darwin-arm64": {
|
|
8
8
|
"zig_target": "aarch64-macos",
|
|
9
|
-
"sha256": "
|
|
9
|
+
"sha256": "e230b49c36db62c3a5c9cf62e316b637ffff7452335211f63c390aab1a13e250",
|
|
10
|
+
"source": "prebuilt"
|
|
10
11
|
},
|
|
11
12
|
"darwin-x64": {
|
|
12
13
|
"zig_target": "x86_64-macos",
|
|
13
|
-
"sha256": "
|
|
14
|
+
"sha256": "f43bae178982b7d5d7da9d041a2984204afecf60c81f6c037451b372adbd2968"
|
|
14
15
|
},
|
|
15
16
|
"linux-arm64": {
|
|
16
17
|
"zig_target": "aarch64-linux",
|
|
17
|
-
"sha256": "
|
|
18
|
+
"sha256": "8416277825f6d55a2936de06f5dedce8ce1fe9445bb94843edd62103e22f8e0d"
|
|
18
19
|
},
|
|
19
20
|
"linux-x64": {
|
|
20
21
|
"zig_target": "x86_64-linux",
|
|
21
|
-
"sha256": "
|
|
22
|
-
},
|
|
23
|
-
"win-x64": {
|
|
24
|
-
"zig_target": "x86_64-windows",
|
|
25
|
-
"sha256": "176291ad9827a183ba7322ddb56cc1fa5edc7c214a264ecdf8a1d5d18366d686"
|
|
22
|
+
"sha256": "459df714ac61fc906d9234f223791d51359c002a8ecbada9995211df9e0283cd"
|
|
26
23
|
}
|
|
27
24
|
}
|
|
28
25
|
}
|
|
Binary file
|