unbrowse 8.3.0-preview.2 → 8.3.0-preview.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.
@@ -0,0 +1,57 @@
1
+ /**
2
+ * src/sdk/adapters/firecrawl.ts — drop-in replacement for the `@mendable/firecrawl-js`
3
+ * client.
4
+ *
5
+ * Same construction (`new FirecrawlApp({ apiKey })`) and the same method shapes
6
+ * (`scrapeUrl`, `search`, `mapUrl`, `crawlUrl`) returning firecrawl-shaped results — but
7
+ * every call routes through the wallet-sealed unbrowse hole instead of Firecrawl's API.
8
+ * Swap the import, keep your code. Where Firecrawl bills a flat monthly plan, the hole
9
+ * settles each call via x402 — you pay per request, only for what you actually fetch.
10
+ * Inject a `transport`/`wallet` (HoleOptions) for tests or to bind the hole to a wallet.
11
+ */
12
+ import { type HoleOptions } from "../hole.js";
13
+ export interface FirecrawlMetadata {
14
+ sourceURL?: string;
15
+ title?: string;
16
+ description?: string;
17
+ [key: string]: unknown;
18
+ }
19
+ export interface FirecrawlDocument {
20
+ url?: string;
21
+ markdown?: string;
22
+ html?: string;
23
+ metadata?: FirecrawlMetadata;
24
+ }
25
+ export interface ScrapeResponse extends FirecrawlDocument {
26
+ success: boolean;
27
+ }
28
+ export interface SearchResponse {
29
+ success: boolean;
30
+ data: FirecrawlDocument[];
31
+ }
32
+ export interface MapResponse {
33
+ success: boolean;
34
+ links: string[];
35
+ }
36
+ export interface CrawlResponse {
37
+ success: boolean;
38
+ status: string;
39
+ completed: number;
40
+ total: number;
41
+ data: FirecrawlDocument[];
42
+ }
43
+ export declare class FirecrawlApp {
44
+ private readonly hole;
45
+ constructor(opts?: {
46
+ apiKey?: string;
47
+ } & HoleOptions);
48
+ scrapeUrl(url: string, _params?: Record<string, unknown>): Promise<ScrapeResponse>;
49
+ search(query: string, params?: {
50
+ limit?: number;
51
+ } & Record<string, unknown>): Promise<SearchResponse>;
52
+ mapUrl(url: string, _params?: Record<string, unknown>): Promise<MapResponse>;
53
+ crawlUrl(url: string, params?: {
54
+ limit?: number;
55
+ } & Record<string, unknown>): Promise<CrawlResponse>;
56
+ }
57
+ export default FirecrawlApp;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * src/sdk/adapters/firecrawl.ts — drop-in replacement for the `@mendable/firecrawl-js`
3
+ * client.
4
+ *
5
+ * Same construction (`new FirecrawlApp({ apiKey })`) and the same method shapes
6
+ * (`scrapeUrl`, `search`, `mapUrl`, `crawlUrl`) returning firecrawl-shaped results — but
7
+ * every call routes through the wallet-sealed unbrowse hole instead of Firecrawl's API.
8
+ * Swap the import, keep your code. Where Firecrawl bills a flat monthly plan, the hole
9
+ * settles each call via x402 — you pay per request, only for what you actually fetch.
10
+ * Inject a `transport`/`wallet` (HoleOptions) for tests or to bind the hole to a wallet.
11
+ */
12
+ import { createHole } from "../hole.js";
13
+ function toDoc(it) {
14
+ const url = it.url ?? "";
15
+ return {
16
+ url,
17
+ markdown: typeof it.text === "string" ? it.text : undefined,
18
+ metadata: { sourceURL: url, title: it.title ?? undefined },
19
+ };
20
+ }
21
+ export class FirecrawlApp {
22
+ hole;
23
+ constructor(opts = {}) {
24
+ // apiKey is accepted for drop-in compatibility but unused — the hole is
25
+ // wallet-sealed and settles per call via x402, not a Firecrawl key.
26
+ const { apiKey: _apiKey, ...holeOpts } = opts;
27
+ this.hole = createHole(holeOpts);
28
+ }
29
+ async scrapeUrl(url, _params = {}) {
30
+ const r = await this.hole.fill({ intent: `contents of ${url}`, url });
31
+ const first = r.items[0];
32
+ const doc = toDoc(first ? { ...first, url } : { url });
33
+ return { success: true, ...doc };
34
+ }
35
+ async search(query, params = {}) {
36
+ const r = await this.hole.fill({ intent: query, params });
37
+ const n = params.limit ?? r.items.length;
38
+ return { success: true, data: r.items.slice(0, n).map(toDoc) };
39
+ }
40
+ async mapUrl(url, _params = {}) {
41
+ const r = await this.hole.fill({ intent: `links on ${url}`, url });
42
+ return { success: true, links: r.items.map((it) => it.url ?? "").filter(Boolean) };
43
+ }
44
+ async crawlUrl(url, params = {}) {
45
+ const r = await this.hole.fill({ intent: `crawl ${url}`, url, params });
46
+ const n = params.limit ?? r.items.length;
47
+ const data = r.items.slice(0, n).map(toDoc);
48
+ return { success: true, status: "completed", completed: data.length, total: data.length, data };
49
+ }
50
+ }
51
+ export default FirecrawlApp;
@@ -6,11 +6,14 @@
6
6
  *
7
7
  * import Exa from "@unbrowse/sdk/adapters/exa"; // was: import Exa from "exa-js"
8
8
  * import { tavily } from "@unbrowse/sdk/adapters/tavily"; // was: from "@tavily/core"
9
+ * import FirecrawlApp from "@unbrowse/sdk/adapters/firecrawl"; // was: from "@mendable/firecrawl-js"
9
10
  * import { Agent } from "@unbrowse/sdk/adapters/browser-use";
10
11
  *
11
- * All of them wrap the same wallet-sealed streaming hole (`../hole.ts`).
12
+ * All of them wrap the same wallet-sealed streaming hole (`../hole.ts`), so each call
13
+ * settles per request via x402 — you pay only for what you fetch, not a flat plan.
12
14
  */
13
15
  export { Exa, type ExaResult, type ExaSearchResponse, type ExaSearchOptions } from "./exa.js";
14
16
  export { tavily, type TavilyClient, type TavilyResult, type TavilySearchResponse } from "./tavily.js";
17
+ export { FirecrawlApp, type FirecrawlDocument, type ScrapeResponse, type SearchResponse, type MapResponse, type CrawlResponse, } from "./firecrawl.js";
15
18
  export { Agent, type AgentOptions, type AgentResult } from "./browser-use.js";
16
19
  export { createHole, Hole, type HoleRequest, type HoleResult, type HoleItem, type HoleOptions, type HoleTransport, type WalletSeal, } from "../hole.js";
@@ -6,11 +6,14 @@
6
6
  *
7
7
  * import Exa from "@unbrowse/sdk/adapters/exa"; // was: import Exa from "exa-js"
8
8
  * import { tavily } from "@unbrowse/sdk/adapters/tavily"; // was: from "@tavily/core"
9
+ * import FirecrawlApp from "@unbrowse/sdk/adapters/firecrawl"; // was: from "@mendable/firecrawl-js"
9
10
  * import { Agent } from "@unbrowse/sdk/adapters/browser-use";
10
11
  *
11
- * All of them wrap the same wallet-sealed streaming hole (`../hole.ts`).
12
+ * All of them wrap the same wallet-sealed streaming hole (`../hole.ts`), so each call
13
+ * settles per request via x402 — you pay only for what you fetch, not a flat plan.
12
14
  */
13
15
  export { Exa } from "./exa.js";
14
16
  export { tavily } from "./tavily.js";
17
+ export { FirecrawlApp, } from "./firecrawl.js";
15
18
  export { Agent } from "./browser-use.js";
16
19
  export { createHole, Hole, } from "../hole.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unbrowse",
3
- "version": "8.3.0-preview.2",
3
+ "version": "8.3.0-preview.4",
4
4
  "description": "Reverse-engineer any website into reusable API skills. Zero-dep single binary with embedded browser engine.",
5
5
  "mcpName": "io.github.unbrowse-ai/unbrowse",
6
6
  "type": "module",