Fruitful Docs
GuidesCapture

Choose an extractor engine

Examine the page data before you select an engine or write selectors.

A binding configures one platform engine. The engine is Fruitful code that reads a page. The binding contains data that tells the engine what to read. Package code does not run during extraction.

The engines

EngineInputUse
dom@1Browser snapshotCollections with CSS selectors for entries
reader@1Browser snapshotFull articles that produce a webDocument
media@1URLVideo and audio through the platform media pipeline
rss@1, http@1Fetched bodyDeclared engines with no available runtime

The extractor engine reference lists each engine's output and availability.

Choose evidence

Use existing approved review fixtures when they reproduce the issue and the request does not specify current behavior. Use a new capture when current behavior matters or existing fixtures cannot answer the question. If the choice is unclear, ask which evidence to use. A result from an old fixture cannot prove current compatibility.

An agent must examine the available CLI commands and connected MCP tools. It must not assume that its host has the user's browser, account, files, or Desktop app. A remote host needs an explicit connection to tools on the user's machine. A local path in a tool result does not transfer the file to another host. Report any missing capability that prevents the requested result.

Prepare the capture route

The authoring capture command requires an existing package definition. For an existing site, use its package. For a new site, adapt a working package with almost the same capture and record requirements. The CLI has no package starter command. plugin generate rebuilds outputs from an existing definition.

If you copy an example, give its packages and Lexicons new reverse-DNS names. Update dependency pins, Lexicon references, and the review root to use those names. Do not use the copied site's cases as evidence for the new site.

The definition must contain a route that matches the target URL. The route needs runsOn and a binding, such as a DOM binding for a collection. It controls login, readiness, hooks, and scrolling. Read Routes are the unit for the route contract. For authenticated pages, follow the login procedure and the private evidence rules before capture.

yarn fruitful authoring capture <url> --package <feed-package> --json

The connected MCP call to capture_page must include packageWorkspace.

Examine the page first

Select the least costly engine that can read the necessary entries without extraction errors. Capture the page through its package route. For private content, first follow Prepare private review evidence. Examine the available WARC and DOM evidence in this order:

  1. Advertised feeds and APIs. Look for RSS or Atom links and JSON responses with the same entries and stable IDs. RSS uses application/rss+xml, and Atom uses application/atom+xml in a link element with rel="alternate". API evidence can include /api/, /graphql, or .json responses. Record the URL, response shape, and identity field. The rss@1 and http@1 runtimes are not available, so continue to the next source.
  2. Embedded structured data. Look for application/ld+json, __NEXT_DATA__, application state, or data-* attributes with IDs and timestamps. Prefer stable attributes to visible text when the DOM engine can read them.
  3. Visible DOM. Write selectors for the rendered entries. Prefer data-testid, ARIA roles, and semantic elements to class names.

Examine a new capture

The local authoring CLI and MCP use the same capture service. Captures, previews, and the browser profile use FRUITFUL_AUTHORING_DATA_ROOT, which defaults to ~/.fruitful. The MCP's prototypes/agent-capture/runs directory contains its tool-call ledger.

yarn fruitful authoring captures --json

With the connected MCP tools:

  1. Use assess_capture to make sure the capture contains the expected page.
  2. Use inspect_capture, inspect_nodes, and inspect_entries to examine the required structure.
  3. Use bounded read_capture slices only when those focused tools omit necessary structure.
  4. Run analyze_binding_coverage over each matched entry.
  5. Give a reason for each required-field gap and rejection, or repair its cause.
  6. Run validate_capture_package with the same capture and package definition.

data-ref values identify nodes in a temporary inspection view. Do not use them as stable package selectors or record identities. Coverage runs deterministically without AI. Coverage tests extraction, while package validation also tests the locked route, transform, records, and Lexicons. Generic detection can suggest selectors, but ContentTypeDetected does not define the package contract. For stored fixtures, use the CLI validation procedure.

Use the first-party bindings for full items

A collection route currently uses dom@1 to supply a package transform. An item route can use a first-party binding to read the full article, video, or audio item:

"bindings": [
  { "id": "front-page", "package": "com.ycombinator.news.binding.front-page@^0.3.0" },
  { "id": "reader", "package": "app.fruitful.binding.reader@^1.0.0" }
]

Pin app.fruitful.binding.reader, .video, and .audio as platform dependencies. Do not add copies to the definition's packages list. Read First-party bindings for their contracts.

Route constraints

Snapshot engines open a browser. Their routes can declare login, load, ready, on, and scroll. Engines that do not open a browser reject these fields. The registry enforces these constraints at publication.

Reference: bindingDependency, Binding package.

On this page