unbrowse 3.6.0-preview.0 → 3.7.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/dist/cli.js +3 -21
- package/dist/mcp.js +4 -4
- package/dist/server.js +31 -22
- package/package.json +3 -1
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.
|
|
34
|
+
var BUILD_RELEASE_VERSION = "3.7.0", BUILD_GIT_SHA = "051ddb5b3add", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy43LjAiLCJnaXRfc2hhIjoiMDUxZGRiNWIzYWRkIiwiY29kZV9oYXNoIjoiNWQ5ZWJmNjE5YzYxIiwidHJhY2VfdmVyc2lvbiI6IjVkOWViZjYxOWM2MUAwNTFkZGI1YjNhZGQiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTEwVDAzOjA3OjU1Ljg4MloifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "TKsUZaH-T1iT7XTgsV8ykdoZDHQj05PQkkmGr0Yf3dQ", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
|
|
35
35
|
|
|
36
36
|
// ../../src/version.ts
|
|
37
37
|
import { createHash } from "crypto";
|
|
@@ -2630,18 +2630,12 @@ async function autonomousLogin(loginUrl, domain) {
|
|
|
2630
2630
|
return { success: false, method: "failed", domain: targetDomain, cookies_stored: 0, error: "No email provider configured (set AGENTMAIL_API_KEY or configure Gmail via gcloud)", duration_ms: elapsed() };
|
|
2631
2631
|
}
|
|
2632
2632
|
log("autonomous-login", `starting for ${targetDomain} — url: ${loginUrl}`);
|
|
2633
|
-
const prevHeadless = process.env.HEADLESS;
|
|
2634
|
-
process.env.HEADLESS = "false";
|
|
2635
2633
|
let tabId;
|
|
2636
2634
|
try {
|
|
2637
2635
|
await start();
|
|
2638
2636
|
tabId = await getDefaultTab();
|
|
2639
2637
|
await networkEnable(tabId);
|
|
2640
2638
|
} catch (err) {
|
|
2641
|
-
if (prevHeadless !== undefined)
|
|
2642
|
-
process.env.HEADLESS = prevHeadless;
|
|
2643
|
-
else
|
|
2644
|
-
delete process.env.HEADLESS;
|
|
2645
2639
|
return { success: false, method: "failed", domain: targetDomain, cookies_stored: 0, error: `Kuri start failed: ${err}`, duration_ms: elapsed() };
|
|
2646
2640
|
}
|
|
2647
2641
|
try {
|
|
@@ -2730,12 +2724,7 @@ async function autonomousLogin(loginUrl, domain) {
|
|
|
2730
2724
|
};
|
|
2731
2725
|
}
|
|
2732
2726
|
return { success: false, method: "failed", domain: targetDomain, email: agentEmail, cookies_stored: 0, error: "login flow completed but no auth cookies detected", duration_ms: elapsed() };
|
|
2733
|
-
} finally {
|
|
2734
|
-
if (prevHeadless !== undefined)
|
|
2735
|
-
process.env.HEADLESS = prevHeadless;
|
|
2736
|
-
else
|
|
2737
|
-
delete process.env.HEADLESS;
|
|
2738
|
-
}
|
|
2727
|
+
} finally {}
|
|
2739
2728
|
}
|
|
2740
2729
|
var OTP_FILL_TIMEOUT_MS = 120000, POST_SUBMIT_SETTLE_MS = 3000;
|
|
2741
2730
|
var init_autonomous_login = __esm(async () => {
|
|
@@ -3374,8 +3363,6 @@ import fs2 from "node:fs";
|
|
|
3374
3363
|
import path9 from "node:path";
|
|
3375
3364
|
async function bootstrapAgentMailKey() {
|
|
3376
3365
|
log("bootstrap-agentmail", "starting — opening console.agentmail.to");
|
|
3377
|
-
const prevHeadless = process.env.HEADLESS;
|
|
3378
|
-
process.env.HEADLESS = "false";
|
|
3379
3366
|
try {
|
|
3380
3367
|
await start();
|
|
3381
3368
|
const tabId = await getDefaultTab();
|
|
@@ -3496,12 +3483,7 @@ async function bootstrapAgentMailKey() {
|
|
|
3496
3483
|
success: false,
|
|
3497
3484
|
error: "Reached dashboard but could not extract API key. Create one manually at https://console.agentmail.to/dashboard/api-keys"
|
|
3498
3485
|
};
|
|
3499
|
-
} finally {
|
|
3500
|
-
if (prevHeadless !== undefined)
|
|
3501
|
-
process.env.HEADLESS = prevHeadless;
|
|
3502
|
-
else
|
|
3503
|
-
delete process.env.HEADLESS;
|
|
3504
|
-
}
|
|
3486
|
+
} finally {}
|
|
3505
3487
|
}
|
|
3506
3488
|
function persistApiKeyToShell(apiKey) {
|
|
3507
3489
|
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.
|
|
229
|
-
var BUILD_GIT_SHA = "
|
|
228
|
+
var BUILD_RELEASE_VERSION = "3.7.0";
|
|
229
|
+
var BUILD_GIT_SHA = "051ddb5b3add";
|
|
230
230
|
var BUILD_CODE_HASH = "5d9ebf619c61";
|
|
231
|
-
var BUILD_RELEASE_MANIFEST_BASE64 = "
|
|
232
|
-
var BUILD_RELEASE_MANIFEST_SIGNATURE = "
|
|
231
|
+
var BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy43LjAiLCJnaXRfc2hhIjoiMDUxZGRiNWIzYWRkIiwiY29kZV9oYXNoIjoiNWQ5ZWJmNjE5YzYxIiwidHJhY2VfdmVyc2lvbiI6IjVkOWViZjYxOWM2MUAwNTFkZGI1YjNhZGQiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTEwVDAzOjA3OjU1Ljg4MloifQ";
|
|
232
|
+
var BUILD_RELEASE_MANIFEST_SIGNATURE = "TKsUZaH-T1iT7XTgsV8ykdoZDHQj05PQkkmGr0Yf3dQ";
|
|
233
233
|
var BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
|
|
234
234
|
|
|
235
235
|
// ../../src/version.ts
|
package/dist/server.js
CHANGED
|
@@ -7096,7 +7096,7 @@ var init_capture = __esm(async () => {
|
|
|
7096
7096
|
});
|
|
7097
7097
|
|
|
7098
7098
|
// ../../src/build-info.generated.ts
|
|
7099
|
-
var BUILD_RELEASE_VERSION = "3.
|
|
7099
|
+
var BUILD_RELEASE_VERSION = "3.7.0", BUILD_GIT_SHA = "051ddb5b3add", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy43LjAiLCJnaXRfc2hhIjoiMDUxZGRiNWIzYWRkIiwiY29kZV9oYXNoIjoiNWQ5ZWJmNjE5YzYxIiwidHJhY2VfdmVyc2lvbiI6IjVkOWViZjYxOWM2MUAwNTFkZGI1YjNhZGQiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTEwVDAzOjA3OjU1Ljg4MloifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "TKsUZaH-T1iT7XTgsV8ykdoZDHQj05PQkkmGr0Yf3dQ", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
|
|
7100
7100
|
|
|
7101
7101
|
// ../../src/version.ts
|
|
7102
7102
|
import { createHash } from "crypto";
|
|
@@ -10893,18 +10893,12 @@ async function autonomousLogin(loginUrl, domain) {
|
|
|
10893
10893
|
return { success: false, method: "failed", domain: targetDomain, cookies_stored: 0, error: "No email provider configured (set AGENTMAIL_API_KEY or configure Gmail via gcloud)", duration_ms: elapsed() };
|
|
10894
10894
|
}
|
|
10895
10895
|
log("autonomous-login", `starting for ${targetDomain} — url: ${loginUrl}`);
|
|
10896
|
-
const prevHeadless = process.env.HEADLESS;
|
|
10897
|
-
process.env.HEADLESS = "false";
|
|
10898
10896
|
let tabId;
|
|
10899
10897
|
try {
|
|
10900
10898
|
await start();
|
|
10901
10899
|
tabId = await getDefaultTab();
|
|
10902
10900
|
await networkEnable(tabId);
|
|
10903
10901
|
} catch (err) {
|
|
10904
|
-
if (prevHeadless !== undefined)
|
|
10905
|
-
process.env.HEADLESS = prevHeadless;
|
|
10906
|
-
else
|
|
10907
|
-
delete process.env.HEADLESS;
|
|
10908
10902
|
return { success: false, method: "failed", domain: targetDomain, cookies_stored: 0, error: `Kuri start failed: ${err}`, duration_ms: elapsed() };
|
|
10909
10903
|
}
|
|
10910
10904
|
try {
|
|
@@ -10993,12 +10987,7 @@ async function autonomousLogin(loginUrl, domain) {
|
|
|
10993
10987
|
};
|
|
10994
10988
|
}
|
|
10995
10989
|
return { success: false, method: "failed", domain: targetDomain, email: agentEmail, cookies_stored: 0, error: "login flow completed but no auth cookies detected", duration_ms: elapsed() };
|
|
10996
|
-
} finally {
|
|
10997
|
-
if (prevHeadless !== undefined)
|
|
10998
|
-
process.env.HEADLESS = prevHeadless;
|
|
10999
|
-
else
|
|
11000
|
-
delete process.env.HEADLESS;
|
|
11001
|
-
}
|
|
10990
|
+
} finally {}
|
|
11002
10991
|
}
|
|
11003
10992
|
var OTP_FILL_TIMEOUT_MS = 120000, POST_SUBMIT_SETTLE_MS = 3000;
|
|
11004
10993
|
var init_autonomous_login = __esm(async () => {
|
|
@@ -15506,6 +15495,7 @@ __export(exports_execution, {
|
|
|
15506
15495
|
buildCanonicalDocumentEndpoint: () => buildCanonicalDocumentEndpoint
|
|
15507
15496
|
});
|
|
15508
15497
|
import { nanoid as nanoid6 } from "nanoid";
|
|
15498
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
15509
15499
|
function stampTrace(trace) {
|
|
15510
15500
|
trace.trace_version = TRACE_VERSION;
|
|
15511
15501
|
return trace;
|
|
@@ -16100,8 +16090,9 @@ function buildCanonicalDocumentEndpoint(url, intent, authRequired = false) {
|
|
|
16100
16090
|
const replayTemplate = deriveStructuredDataReplayTemplate(url);
|
|
16101
16091
|
if (replayUrl === url && replayTemplate === url)
|
|
16102
16092
|
return;
|
|
16093
|
+
const canonicalId = createHash5("sha1").update(replayTemplate !== url ? replayTemplate : replayUrl).digest("base64url").slice(0, 21);
|
|
16103
16094
|
const endpoint = {
|
|
16104
|
-
endpoint_id:
|
|
16095
|
+
endpoint_id: canonicalId,
|
|
16105
16096
|
method: "GET",
|
|
16106
16097
|
url_template: replayTemplate !== url ? replayTemplate : replayUrl,
|
|
16107
16098
|
idempotency: "safe",
|
|
@@ -19126,10 +19117,10 @@ var init_timing_economics = __esm(() => {
|
|
|
19126
19117
|
});
|
|
19127
19118
|
|
|
19128
19119
|
// ../../src/routing-telemetry.ts
|
|
19129
|
-
import { createHash as
|
|
19120
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
19130
19121
|
import { nanoid as nanoid8 } from "nanoid";
|
|
19131
19122
|
function stableHash(value) {
|
|
19132
|
-
return
|
|
19123
|
+
return createHash6("sha256").update(JSON.stringify(value)).digest("hex").slice(0, 24);
|
|
19133
19124
|
}
|
|
19134
19125
|
function sanitizeScalar(value) {
|
|
19135
19126
|
if (value == null)
|
|
@@ -19483,7 +19474,7 @@ function applyVerificationResults(skill, verification) {
|
|
|
19483
19474
|
import { nanoid as nanoid9 } from "nanoid";
|
|
19484
19475
|
import { existsSync as existsSync13, writeFileSync as writeFileSync8, readFileSync as readFileSync8, mkdirSync as mkdirSync9, readdirSync as readdirSync6 } from "node:fs";
|
|
19485
19476
|
import { dirname as dirname2, join as join12 } from "node:path";
|
|
19486
|
-
import { createHash as
|
|
19477
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
19487
19478
|
function summarizeSchema(schema, maxDepth = 3) {
|
|
19488
19479
|
function walk(s, depth) {
|
|
19489
19480
|
if (depth <= 0)
|
|
@@ -19611,7 +19602,7 @@ function scopedResolveCacheKeys(scope, key) {
|
|
|
19611
19602
|
return scope === "global" ? [scopedCacheKey("global", key)] : [scopedCacheKey(scope, key), scopedCacheKey("global", key)];
|
|
19612
19603
|
}
|
|
19613
19604
|
function snapshotPathForCacheKey(cacheKey) {
|
|
19614
|
-
const digest =
|
|
19605
|
+
const digest = createHash7("sha1").update(cacheKey).digest("hex");
|
|
19615
19606
|
return join12(SKILL_SNAPSHOT_DIR, `${digest}.json`);
|
|
19616
19607
|
}
|
|
19617
19608
|
function writeSkillSnapshot(cacheKey, skill) {
|
|
@@ -19933,10 +19924,17 @@ function withContextReplayEndpoint(skill, intent, contextUrl) {
|
|
|
19933
19924
|
if (skill.endpoints.some((endpoint) => endpoint.method === canonical.method && endpoint.url_template === canonical.url_template)) {
|
|
19934
19925
|
return skill;
|
|
19935
19926
|
}
|
|
19936
|
-
|
|
19927
|
+
const augmented = {
|
|
19937
19928
|
...skill,
|
|
19938
19929
|
endpoints: [canonical, ...skill.endpoints]
|
|
19939
19930
|
};
|
|
19931
|
+
try {
|
|
19932
|
+
const existing = findExistingSkillForDomain(skill.domain);
|
|
19933
|
+
if (!existing || !existing.endpoints.some((ep) => ep.endpoint_id === canonical.endpoint_id)) {
|
|
19934
|
+
cachePublishedSkill(augmented);
|
|
19935
|
+
}
|
|
19936
|
+
} catch {}
|
|
19937
|
+
return augmented;
|
|
19940
19938
|
}
|
|
19941
19939
|
function isSearchLikeIntent(intent, contextUrl) {
|
|
19942
19940
|
if (/\b(search|find|lookup|browse|discover)\b/i.test(intent ?? ""))
|
|
@@ -19955,7 +19953,7 @@ function buildLocalCanonicalReplaySkill(intent, contextUrl) {
|
|
|
19955
19953
|
const domain = new URL(contextUrl).hostname.replace(/^www\./, "");
|
|
19956
19954
|
const now = new Date().toISOString();
|
|
19957
19955
|
const skill = {
|
|
19958
|
-
skill_id: `canonical-${
|
|
19956
|
+
skill_id: `canonical-${createHash7("sha1").update(contextUrl).digest("hex").slice(0, 12)}`,
|
|
19959
19957
|
version: "1.0.0",
|
|
19960
19958
|
schema_version: "1",
|
|
19961
19959
|
name: `Canonical replay for ${domain}`,
|
|
@@ -22157,7 +22155,18 @@ async function resolveAndExecute(intent, params = {}, context, projection, optio
|
|
|
22157
22155
|
continue;
|
|
22158
22156
|
if (targetRegDomain && getRegistrableDomain(skill.domain) !== targetRegDomain)
|
|
22159
22157
|
continue;
|
|
22160
|
-
|
|
22158
|
+
let endpointId = extractEndpointId(c.metadata) ?? undefined;
|
|
22159
|
+
if (endpointId && !skill.endpoints.some((ep) => ep.endpoint_id === endpointId)) {
|
|
22160
|
+
const vecUrl = c.metadata?.url_template;
|
|
22161
|
+
const urlMatch = vecUrl ? skill.endpoints.find((ep) => ep.url_template === vecUrl) : undefined;
|
|
22162
|
+
if (urlMatch) {
|
|
22163
|
+
console.log(`[marketplace] vecdb endpoint ${endpointId} stale → recovered via URL match: ${urlMatch.endpoint_id}`);
|
|
22164
|
+
endpointId = urlMatch.endpoint_id;
|
|
22165
|
+
} else {
|
|
22166
|
+
console.log(`[marketplace] vecdb endpoint ${endpointId} not found on skill ${skillId} — dropping to skill-level match`);
|
|
22167
|
+
endpointId = undefined;
|
|
22168
|
+
}
|
|
22169
|
+
}
|
|
22161
22170
|
ranked.push({
|
|
22162
22171
|
candidate: c,
|
|
22163
22172
|
skill,
|
|
@@ -27588,7 +27597,7 @@ var init_routes = __esm(async () => {
|
|
|
27588
27597
|
]);
|
|
27589
27598
|
BETA_API_URL = process.env.UNBROWSE_BACKEND_URL || DEFAULT_BACKEND_URL;
|
|
27590
27599
|
TRACES_DIR = process.env.TRACES_DIR ?? join17(process.cwd(), "traces");
|
|
27591
|
-
BROWSE_BROKER_MAX = Math.max(1, Number(process.env.KURI_MULTI_BROKER_MAX ?? "
|
|
27600
|
+
BROWSE_BROKER_MAX = Math.max(1, Number(process.env.KURI_MULTI_BROKER_MAX ?? "1"));
|
|
27592
27601
|
BROWSE_BROKER_BASE_PORT = Number(process.env.KURI_PORT ?? "7700");
|
|
27593
27602
|
browseSessions = new Map;
|
|
27594
27603
|
STATS_CACHE_TTL = 5 * 60 * 1000;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unbrowse",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0",
|
|
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": {
|
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
"@fastify/rate-limit": "^10.3.0",
|
|
30
30
|
"@cascade-fyi/splits-sdk": "^0.11.1",
|
|
31
31
|
"@solana/kit": "^6.6.0",
|
|
32
|
+
"@x402/fetch": "^2.9.0",
|
|
33
|
+
"agentmail": "^0.4.18",
|
|
32
34
|
"bs58": "^6.0.0",
|
|
33
35
|
"cheerio": "^1.2.0",
|
|
34
36
|
"dotenv": "^17.3.1",
|