unbrowse 3.2.4 → 3.3.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 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.3", BUILD_GIT_SHA = "8932456cbb1b", BUILD_CODE_HASH = "1488fc1d92b7", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy4yLjMiLCJnaXRfc2hhIjoiODkzMjQ1NmNiYjFiIiwiY29kZV9oYXNoIjoiMTQ4OGZjMWQ5MmI3IiwidHJhY2VfdmVyc2lvbiI6IjE0ODhmYzFkOTJiN0A4OTMyNDU2Y2JiMWIiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTA2VDE1OjE4OjE4LjA4N1oifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "mtE78cgbLEvf2MfVwRONdfoW6L2kH5hlOvD6Jbp7s9I", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
34
+ var BUILD_RELEASE_VERSION = "3.3.0", BUILD_GIT_SHA = "d503455236d3", BUILD_CODE_HASH = "1488fc1d92b7", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy4zLjAiLCJnaXRfc2hhIjoiZDUwMzQ1NTIzNmQzIiwiY29kZV9oYXNoIjoiMTQ4OGZjMWQ5MmI3IiwidHJhY2VfdmVyc2lvbiI6IjE0ODhmYzFkOTJiN0BkNTAzNDU1MjM2ZDMiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTA2VDE2OjQyOjAxLjcyOFoifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "QZKL6cxuZOauUsIdM3tms9r0wyOad9mfa9StUKd4v44", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
35
35
 
36
36
  // ../../src/version.ts
37
37
  import { createHash } from "crypto";
@@ -3387,7 +3387,8 @@ async function cmdResolve(flags) {
3387
3387
  params: { endpoint_id: endpointId, ...extraParams },
3388
3388
  intent,
3389
3389
  projection: { raw: true },
3390
- ...flags["confirm-third-party-terms"] ? { confirm_third_party_terms: true } : {}
3390
+ ...flags["confirm-third-party-terms"] ? { confirm_third_party_terms: true } : {},
3391
+ ...flags["skip-robots"] ? { skip_robots_check: true } : {}
3391
3392
  };
3392
3393
  }, endpointNeedsThirdPartyTermsConfirmation = function(endpoint) {
3393
3394
  return endpoint.requires_third_party_terms_confirmation === true;
@@ -3419,6 +3420,8 @@ async function cmdResolve(flags) {
3419
3420
  body.confirm_third_party_terms = true;
3420
3421
  if (flags["force-capture"])
3421
3422
  body.force_capture = true;
3423
+ if (flags["skip-robots"])
3424
+ body.skip_robots_check = true;
3422
3425
  body.projection = { raw: true };
3423
3426
  const startedAt = Date.now();
3424
3427
  async function resolveOnce(message = "Still working. Searching cached routes...") {
@@ -3628,6 +3631,8 @@ async function cmdExecute(flags) {
3628
3631
  body.confirm_unsafe = true;
3629
3632
  if (flags["confirm-third-party-terms"])
3630
3633
  body.confirm_third_party_terms = true;
3634
+ if (flags["skip-robots"])
3635
+ body.skip_robots_check = true;
3631
3636
  body.projection = { raw: true };
3632
3637
  let result = await withPendingNotice(api2("POST", `/v1/skills/${skillId}/execute`, body), "Still working. This endpoint may require browser replay or first-time auth/capture setup.");
3633
3638
  if (isResolveSuccessResult(result)) {
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.3";
229
- var BUILD_GIT_SHA = "8932456cbb1b";
228
+ var BUILD_RELEASE_VERSION = "3.3.0";
229
+ var BUILD_GIT_SHA = "d503455236d3";
230
230
  var BUILD_CODE_HASH = "1488fc1d92b7";
231
- var BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy4yLjMiLCJnaXRfc2hhIjoiODkzMjQ1NmNiYjFiIiwiY29kZV9oYXNoIjoiMTQ4OGZjMWQ5MmI3IiwidHJhY2VfdmVyc2lvbiI6IjE0ODhmYzFkOTJiN0A4OTMyNDU2Y2JiMWIiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTA2VDE1OjE4OjE4LjA4N1oifQ";
232
- var BUILD_RELEASE_MANIFEST_SIGNATURE = "mtE78cgbLEvf2MfVwRONdfoW6L2kH5hlOvD6Jbp7s9I";
231
+ var BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy4zLjAiLCJnaXRfc2hhIjoiZDUwMzQ1NTIzNmQzIiwiY29kZV9oYXNoIjoiMTQ4OGZjMWQ5MmI3IiwidHJhY2VfdmVyc2lvbiI6IjE0ODhmYzFkOTJiN0BkNTAzNDU1MjM2ZDMiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTA2VDE2OjQyOjAxLjcyOFoifQ";
232
+ var BUILD_RELEASE_MANIFEST_SIGNATURE = "QZKL6cxuZOauUsIdM3tms9r0wyOad9mfa9StUKd4v44";
233
233
  var BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
234
234
 
235
235
  // ../../src/version.ts
@@ -1658,6 +1658,7 @@ var tools = [
1658
1658
  dry_run: { type: "boolean", description: "Preview unsafe calls without applying them." },
1659
1659
  confirm_third_party_terms: { type: "boolean", description: "Explicitly confirm policy-sensitive third-party terms risk for flagged domains/actions." },
1660
1660
  force_capture: { type: "boolean", description: "Bypass cache and re-capture the exact URL." },
1661
+ skip_robots: { type: "boolean", description: "Bypass robots.txt compliance check." },
1661
1662
  raw: { type: "boolean", description: "Keep raw projection enabled. Default true." },
1662
1663
  schema: { type: "boolean", description: "Return a schema tree instead of data." },
1663
1664
  path: { type: "string", description: "Drill into the result before returning it, e.g. data.items[] ." },
@@ -1692,6 +1693,8 @@ var tools = [
1692
1693
  body.confirm_third_party_terms = true;
1693
1694
  if (args.force_capture === true)
1694
1695
  body.force_capture = true;
1696
+ if (args.skip_robots === true)
1697
+ body.skip_robots_check = true;
1695
1698
  let result = await api2("POST", "/v1/intent/resolve", body);
1696
1699
  const authError = resolveNestedError(result);
1697
1700
  if (authError === "auth_required") {
@@ -1725,6 +1728,7 @@ var tools = [
1725
1728
  dry_run: { type: "boolean", description: "Preview unsafe calls without applying them." },
1726
1729
  confirm_unsafe: { type: "boolean", description: "Confirm mutation if the endpoint is unsafe." },
1727
1730
  confirm_third_party_terms: { type: "boolean", description: "Explicitly confirm policy-sensitive third-party terms risk for flagged domains/actions." },
1731
+ skip_robots: { type: "boolean", description: "Bypass robots.txt compliance check." },
1728
1732
  raw: { type: "boolean", description: "Keep raw projection enabled. Default true." },
1729
1733
  schema: { type: "boolean", description: "Return a schema tree instead of data." },
1730
1734
  path: { type: "string", description: "Drill into the result before returning it, e.g. data.items[] ." },
@@ -1754,6 +1758,8 @@ var tools = [
1754
1758
  body.confirm_unsafe = true;
1755
1759
  if (args.confirm_third_party_terms === true)
1756
1760
  body.confirm_third_party_terms = true;
1761
+ if (args.skip_robots === true)
1762
+ body.skip_robots_check = true;
1757
1763
  const result = await api2("POST", `/v1/skills/${args.skill}/execute`, body);
1758
1764
  const nestedError = resolveNestedError(result);
1759
1765
  recordImpactForTool("execute", result, args);
package/dist/server.js CHANGED
@@ -6884,7 +6884,7 @@ var init_capture = __esm(async () => {
6884
6884
  });
6885
6885
 
6886
6886
  // ../../src/build-info.generated.ts
6887
- var BUILD_RELEASE_VERSION = "3.2.3", BUILD_GIT_SHA = "8932456cbb1b", BUILD_CODE_HASH = "1488fc1d92b7", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy4yLjMiLCJnaXRfc2hhIjoiODkzMjQ1NmNiYjFiIiwiY29kZV9oYXNoIjoiMTQ4OGZjMWQ5MmI3IiwidHJhY2VfdmVyc2lvbiI6IjE0ODhmYzFkOTJiN0A4OTMyNDU2Y2JiMWIiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTA2VDE1OjE4OjE4LjA4N1oifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "mtE78cgbLEvf2MfVwRONdfoW6L2kH5hlOvD6Jbp7s9I", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
6887
+ var BUILD_RELEASE_VERSION = "3.3.0", BUILD_GIT_SHA = "d503455236d3", BUILD_CODE_HASH = "1488fc1d92b7", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiMy4zLjAiLCJnaXRfc2hhIjoiZDUwMzQ1NTIzNmQzIiwiY29kZV9oYXNoIjoiMTQ4OGZjMWQ5MmI3IiwidHJhY2VfdmVyc2lvbiI6IjE0ODhmYzFkOTJiN0BkNTAzNDU1MjM2ZDMiLCJpc3N1ZWRfYXQiOiIyMDI2LTA0LTA2VDE2OjQyOjAxLjcyOFoifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "QZKL6cxuZOauUsIdM3tms9r0wyOad9mfa9StUKd4v44", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai";
6888
6888
 
6889
6889
  // ../../src/version.ts
6890
6890
  import { createHash } from "crypto";
@@ -13242,6 +13242,8 @@ function getEndpointPolicy(endpoint) {
13242
13242
  return;
13243
13243
  if (matched.require_for_mutations && !MUTATION_METHODS.has(endpoint.method))
13244
13244
  return;
13245
+ if (endpoint.idempotency === "safe" || endpoint.idempotency === "read")
13246
+ return;
13245
13247
  return {
13246
13248
  requires_third_party_terms_confirmation: true,
13247
13249
  policy_domain: matched.domain,
@@ -25202,11 +25204,11 @@ async function registerRoutes(app) {
25202
25204
  });
25203
25205
  app.post("/v1/intent/resolve", { config: { rateLimit: ROUTE_LIMITS["/v1/intent/resolve"] } }, async (req, reply) => {
25204
25206
  const clientScope = clientScopeFor(req);
25205
- const { intent, params, context, projection, confirm_unsafe, confirm_third_party_terms, dry_run, force_capture } = req.body;
25207
+ const { intent, params, context, projection, confirm_unsafe, confirm_third_party_terms, dry_run, force_capture, skip_robots_check } = req.body;
25206
25208
  if (!intent)
25207
25209
  return reply.code(400).send({ error: "intent required" });
25208
25210
  try {
25209
- const result = await resolveAndExecute(intent, params ?? {}, context, projection, { confirm_unsafe, confirm_third_party_terms, dry_run, force_capture, client_scope: clientScope });
25211
+ const result = await resolveAndExecute(intent, params ?? {}, context, projection, { confirm_unsafe, confirm_third_party_terms, dry_run, force_capture, skip_robots_check, client_scope: clientScope });
25210
25212
  const res = attachAgentOutcomeHints({ ...result }, {
25211
25213
  skill: result.skill,
25212
25214
  endpointId: result.trace.endpoint_id,
@@ -25403,7 +25405,7 @@ async function registerRoutes(app) {
25403
25405
  app.post("/v1/skills/:skill_id/execute", { config: { rateLimit: ROUTE_LIMITS["/v1/skills/:skill_id/execute"] } }, async (req, reply) => {
25404
25406
  const clientScope = clientScopeFor(req);
25405
25407
  const { skill_id } = req.params;
25406
- const { params, projection, confirm_unsafe, confirm_third_party_terms, dry_run, intent, context_url } = req.body;
25408
+ const { params, projection, confirm_unsafe, confirm_third_party_terms, dry_run, intent, context_url, skip_robots_check } = req.body;
25407
25409
  let skill = getRecentLocalSkill(skill_id, clientScope);
25408
25410
  if (!skill) {
25409
25411
  const { findExistingSkillForDomain: findLocal } = await Promise.resolve().then(() => (init_client2(), exports_client2));
@@ -25425,7 +25427,7 @@ async function registerRoutes(app) {
25425
25427
  ...context_url && typeof params?.url !== "string" ? { url: context_url } : {}
25426
25428
  };
25427
25429
  try {
25428
- const execResult = await executeSkill(skill, execParams, projection, { confirm_unsafe, confirm_third_party_terms, dry_run, intent, contextUrl: context_url, client_scope: clientScope });
25430
+ const execResult = await executeSkill(skill, execParams, projection, { confirm_unsafe, confirm_third_party_terms, dry_run, skip_robots_check, intent, contextUrl: context_url, client_scope: clientScope });
25429
25431
  saveTrace(execResult.trace);
25430
25432
  if (execResult.trace.endpoint_id) {
25431
25433
  recordExecution(skill.skill_id, execResult.trace.endpoint_id, execResult.trace, skill).catch(() => {});
@@ -25436,7 +25438,7 @@ async function registerRoutes(app) {
25436
25438
  if (execResult.trace.status_code === 404 && skill.domain && skill.intent_signature && skill.execution_type !== "browser-capture") {
25437
25439
  try {
25438
25440
  const recoveryUrl = context_url || typeof execParams.url === "string" && execParams.url || skill.endpoints.find((endpoint) => typeof endpoint.trigger_url === "string" && endpoint.trigger_url)?.trigger_url || `https://${skill.domain}`;
25439
- const freshResult = await resolveAndExecute(intent || skill.intent_signature, { ...execParams, url: recoveryUrl }, { url: recoveryUrl }, projection, { confirm_unsafe, confirm_third_party_terms, dry_run, intent: intent || skill.intent_signature, client_scope: clientScope });
25441
+ const freshResult = await resolveAndExecute(intent || skill.intent_signature, { ...execParams, url: recoveryUrl }, { url: recoveryUrl }, projection, { confirm_unsafe, confirm_third_party_terms, dry_run, skip_robots_check, intent: intent || skill.intent_signature, client_scope: clientScope });
25440
25442
  saveTrace(freshResult.trace);
25441
25443
  if (freshResult.trace?.skill_id && freshResult.trace?.endpoint_id) {
25442
25444
  recordExecution(freshResult.trace.skill_id, freshResult.trace.endpoint_id, freshResult.trace, skill).catch(() => {});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unbrowse",
3
- "version": "3.2.4",
3
+ "version": "3.3.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": {