Skip to content

feat(crawl): return each page as Markdown, and choose how a crawl finds URLs - #44

Open
zenrows-dev-pool[bot] wants to merge 6 commits into
mainfrom
feat/crawl-markdown
Open

zenrows-dev-pool[bot] wants to merge 6 commits into
mainfrom
feat/crawl-markdown

Conversation

@zenrows-dev-pool

@zenrows-dev-pool zenrows-dev-pool Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Summary

crawl create also takes --discovery links, and refuses any other value
locally.

crawl create --output-format markdown stores each kept page converted to
Markdown, read back with crawl content and crawl download as
--output-format html already was. A crawl also reports discovery, so
crawl get --json carries it instead of dropping it.

What the task asked for

The command had drifted from the API it wraps. It refused every output format
but html, and its result type dropped the discovery field a crawl reports.

How the check confirmed it

npm run typecheck and npm test both pass, 364 tests. This change adds two
checks to the Crawl acceptance suite. Check 22 covers a create with
--output-format markdown. Check 23 covers a value that is neither, which the
command still refuses locally before any network call.

A running Crawl service took output_format: "markdown" and came back with
markdown.

Encoded by: acceptance checks 22, 23 and 24, and tests/crawl-command.test.ts.

The test that listed --discovery among unknown flags now checks it sends
links and refuses every other value before any network call.

How to try it

zenrows crawl create https://example.com/ --output-format markdown --max-pages 20 --follow
zenrows crawl results <id> --json        # fetched rows carry content_url
zenrows crawl content <id> <content_id>  # the page, as Markdown
zenrows crawl create https://example.com/ --output-format pdf   # refused locally

Provenance

The command checks the format itself and names what it takes, which is how it
already handled html. A reader of --help sees the choice without a round
trip to the API.

The lock records the API description this surface follows. It lists
GET /healthz and POST /internal/v1/crawls/{crawl_id}/stop as pending. Both
are in the description and callers cannot reach either. Listing them keeps a
change to either from reading as drift here.

Review

Severity File and line Summary
Low — No finding survived the pass.

One pass, by the author. Human must verify: nothing outstanding.

Deviations

None.

Record owed

None.

`crawl create --output-format markdown` stores each kept URL's page
converted to Markdown, read back with `crawl content` and `crawl
download` as `--output-format html` already was. A value that is neither
is still refused locally, before any network call.

A crawl also reports `discovery`, the strategies it found URLs with, so
`crawl get --json` carries it instead of dropping it.
The lock names the API description this surface was synced to, by its
blob id, so a later drift check compares against it instead of reporting
the surface as never synced. Two operations in that description are not
served to callers and no surface exposes them; the lock lists them as
pending, so a change to either does not read as drift here.
`crawl create --discovery links` asks for the strategy a crawl finds URLs
with on each page it walks: the links in each page's HTML, which is also
what it runs with when the flag is left out. Any other value is refused
locally, before any network call.

The acceptance harness also passes the run's base URL to the CLI. The
CLI reads its own variable, which the harness never set, so a run against
another base URL still sent its calls to production.
@zenrows-dev-pool zenrows-dev-pool Bot changed the title feat(crawl): return each page as Markdown feat(crawl): return each page as Markdown, and choose how a crawl finds URLs Oct 15, 2026
@StefanoGuerrini
StefanoGuerrini marked this pull request as ready for review October 15, 2026 14:59
@StefanoGuerrini
StefanoGuerrini self-requested a review October 15, 2026 14:59
StefanoGuerrini and others added 3 commits October 15, 2026 17:03
crawl results said partial false on any ended crawl. After a stop, the
API keeps next_cursor set while pages still in flight can add URLs, so
the list was not complete yet. partial now follows next_cursor, and a
partial read carries a note to read the results again later.
The values that the json output and pagination discovery use stay off for every user. The lock now records them as held, so the drift check reads their flag on each pass.
…arrive

A stop reads stopped at once, but the API still reads the pages in flight for up to 10 minutes and builds the file from what it kept until then. download now asks the API, as results does, and says to download again later while it is not done.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant