unbrowse 2.8.2 → 2.8.4

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
@@ -11161,12 +11161,11 @@ async function executeEndpoint(skill, endpoint, params = {}, projection, options
11161
11161
  return `${c.name}=${v}`;
11162
11162
  }).join("; ");
11163
11163
  headers["cookie"] = cookieStr;
11164
- if (!headers["x-csrf-token"] && !headers["x-xsrf-token"]) {
11165
- const csrfCookie = cookies.find((c) => /^(ct0|csrf_token|_csrf|csrftoken|XSRF-TOKEN|_xsrf)$/i.test(c.name));
11166
- if (csrfCookie) {
11167
- const v = csrfCookie.value.startsWith('"') && csrfCookie.value.endsWith('"') ? csrfCookie.value.slice(1, -1) : csrfCookie.value;
11168
- headers["x-csrf-token"] = v;
11169
- }
11164
+ const csrfCookie = cookies.find((c) => /^(ct0|csrf_token|_csrf|csrftoken|XSRF-TOKEN|_xsrf)$/i.test(c.name));
11165
+ if (csrfCookie) {
11166
+ const v = csrfCookie.value.startsWith(") && csrfCookie.value.endsWith(") ? csrfCookie.value.slice(1, -1) : csrfCookie.value;
11167
+ headers["x-csrf-token"] = v;
11168
+ headers["x-xsrf-token"] = v;
11170
11169
  }
11171
11170
  }
11172
11171
  if (endpoint.csrf_plan && cookies.length > 0) {
@@ -16742,7 +16741,20 @@ async function registerRoutes(app) {
16742
16741
  const clientScope = clientScopeFor(req);
16743
16742
  const { skill_id } = req.params;
16744
16743
  const { params, projection, confirm_unsafe, dry_run, intent, context_url } = req.body;
16745
- const skill = getRecentLocalSkill(skill_id, clientScope) ?? await getSkill2(skill_id, clientScope);
16744
+ let skill = getRecentLocalSkill(skill_id, clientScope);
16745
+ if (!skill) {
16746
+ const { findExistingSkillForDomain: findLocal } = await Promise.resolve().then(() => (init_client2(), exports_client2));
16747
+ for (const [, entry] of domainSkillCache) {
16748
+ if (entry.skillId === skill_id && entry.localSkillPath) {
16749
+ try {
16750
+ skill = JSON.parse(__require("fs").readFileSync(entry.localSkillPath, "utf-8"));
16751
+ } catch {}
16752
+ break;
16753
+ }
16754
+ }
16755
+ }
16756
+ if (!skill)
16757
+ skill = await getSkill2(skill_id, clientScope);
16746
16758
  if (!skill)
16747
16759
  return reply.code(404).send({ error: "Skill not found" });
16748
16760
  const execParams = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unbrowse",
3
- "version": "2.8.2",
3
+ "version": "2.8.4",
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": {
@@ -410,7 +410,21 @@ export async function registerRoutes(app: FastifyInstance) {
410
410
  intent?: string;
411
411
  context_url?: string;
412
412
  };
413
- const skill = getRecentLocalSkill(skill_id, clientScope) ?? await getSkill(skill_id, clientScope);
413
+ // Check local caches first: recent skills domain snapshots → marketplace
414
+ let skill = getRecentLocalSkill(skill_id, clientScope);
415
+ if (!skill) {
416
+ // Check domain snapshot cache — passively indexed skills live here
417
+ const { findExistingSkillForDomain: findLocal } = await import("../client/index.js");
418
+ for (const [, entry] of domainSkillCache) {
419
+ if (entry.skillId === skill_id && entry.localSkillPath) {
420
+ try {
421
+ skill = JSON.parse(require("fs").readFileSync(entry.localSkillPath, "utf-8"));
422
+ } catch { /* snapshot read failed */ }
423
+ break;
424
+ }
425
+ }
426
+ }
427
+ if (!skill) skill = await getSkill(skill_id, clientScope);
414
428
  if (!skill) return reply.code(404).send({ error: "Skill not found" });
415
429
  const execParams = {
416
430
  ...(params ?? {}),
@@ -1880,15 +1880,15 @@ export async function executeEndpoint(
1880
1880
  headers["cookie"] = cookieStr;
1881
1881
 
1882
1882
  // CSRF token auto-detection (bird pattern): many sites require CSRF tokens
1883
- // as both a cookie AND a header. Detect common patterns and replay them.
1884
- if (!headers["x-csrf-token"] && !headers["x-xsrf-token"]) {
1885
- const csrfCookie = cookies.find((c) =>
1886
- /^(ct0|csrf_token|_csrf|csrftoken|XSRF-TOKEN|_xsrf)$/i.test(c.name)
1887
- );
1888
- if (csrfCookie) {
1889
- const v = csrfCookie.value.startsWith('"') && csrfCookie.value.endsWith('"') ? csrfCookie.value.slice(1, -1) : csrfCookie.value;
1890
- headers["x-csrf-token"] = v;
1891
- }
1883
+ // as both a cookie AND a header. The cookie value is always fresher than
1884
+ // any stored vault header, so it ALWAYS overrides.
1885
+ const csrfCookie = cookies.find((c) =>
1886
+ /^(ct0|csrf_token|_csrf|csrftoken|XSRF-TOKEN|_xsrf)$/i.test(c.name)
1887
+ );
1888
+ if (csrfCookie) {
1889
+ const v = csrfCookie.value.startsWith(') && csrfCookie.value.endsWith(') ? csrfCookie.value.slice(1, -1) : csrfCookie.value;
1890
+ headers["x-csrf-token"] = v;
1891
+ headers["x-xsrf-token"] = v;
1892
1892
  }
1893
1893
  }
1894
1894