Repository navigation
Agent mode: scrape, map, crawl, find, extract and interact for AI agents (no LLM) - #5
Open
Shantodotdev wants to merge 30 commits into
Open
Shantodotdev wants to merge 30 commits into
Shantodotdev wants to merge 30 commits into
Conversation
Ensure ephemeral audits run purely in-memory without resolving, modifying, or deleting existing database files or their WAL/SHM artifacts. Add automated test coverage in tests/ephemeral_tests.rs.
…hecksums Remove eval from PATH resolution in install.sh, validate arguments strictly, make SHA-256 checksum verification fail closed by default, support --no-modify-path, and add integration tests in tests/installer_tests.rs.
…dation - Add IP classification to permanently block cloud metadata endpoints (169.254.169.254) and private subnets. - Implement port-aware private host allowlisting with automatic target URL scoping. - Add pre-flight validation and intercept HTTP redirects to prevent internal network pivoting. - Extend crawler engine, single-page inspector, and AI readiness checker with network security options.
- Update McpContext to track network security flags and allowed private hosts. - Add allow_local_network and allowed_private_hosts properties to tool JSON schemas. - Auto-scope raw target URLs in MCP tools while enforcing private network restrictions. - Support running MCP server with configurable network context.
- Add -a, --allow, and --allow-host flags to audit, inspect, and mcp subcommands. - Add --allow-local-network flag to mcp subcommand. - Forward allowed private hosts to crawler config, inspector, and MCP server context.
…tection - Add unit tests for cloud metadata detection, private IP classification, and allowlist extraction. - Add unit tests for port-aware URL safety validation. - Add dual-WireMock end-to-end tests for target auto-scoping and redirect hop defense. - Validate strict blocking of cloud instance metadata endpoints.
- Launch an isolated local Chrome instance or connect to a supplied CDP endpoint.\n- Parse rendered DOMs for crawl reports and discovered links.\n- Add JavaScript SEO diff rules for metadata, content, links, and hydration failures.
- Add a synthetic SPA fixture that changes metadata, content, links, and route state.\n- Exercise Chrome rendering, runtime error capture, JavaScript diff rules, and crawl integration.
…ssion ceiling - Replace unbounded body buffering with chunked streaming capped at 15 MiB. - Stop polling and drop the connection when response exceeds Googlebot indexing limit. - Add is_truncated flag to FetchResult to signal partial document retrieval. - Wrap sitemap GzDecoder with Read::take to enforce 50 MiB decompression limit. - Update test fetch fixtures with is_truncated field.
…ndary - Emit ErrPerfExcessiveHtmlPayload when response stream was truncated at 15 MiB. - Advise users that search engines discard content, links, and schema past 15 MiB. - Retain existing payload warnings for 1.5 MiB and 3.0 MiB thresholds.
…ression bombs - Verify 16 MiB stream is truncated at exactly 15 MiB with is_truncated set to true. - Verify normal pages under 15 MiB are completely retrieved without truncation. - Verify 55 MiB gzip decompression bomb is cleanly rejected without memory bloat. - Verify ErrPerfExcessiveHtmlPayload is emitted when auditing a truncated page.
…cessor seam SeoProcessor owns the single-page and JS-diff rule evaluation and the PageReport build that used to live inline in fetch_and_audit_page. Link candidate filtering and politeness helpers become reusable for other crawl modes. No behaviour change: the full SEO suite passes unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019cgrVnvyqj7Q1ySUtBpVEj
…ent crawls and extraction rules Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019cgrVnvyqj7Q1ySUtBpVEj
Scrape turns one URL into clean Markdown, typed JSON blocks and metadata (rs-trafilatura anchored to the DOM, hidden-text removal, Markdown fast path, PDF text, token budgets). Map lists a site's URLs from sitemaps and page links. Crawl follows same-site links with path filters, AIMD pacing, cross-page boilerplate removal, NDJSON / Markdown-directory sinks and background jobs. Includes an offline eval corpus with a recorded F1 baseline. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019cgrVnvyqj7Q1ySUtBpVEj
…nd crawls Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019cgrVnvyqj7Q1ySUtBpVEj
…les and records Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019cgrVnvyqj7Q1ySUtBpVEj
…ring Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019cgrVnvyqj7Q1ySUtBpVEj
Scrape, map, crawl (start, poll, cancel), find, extract and interact endpoints with bearer keys, per-key rate limits, body and crawl caps, loopback-only binding without keys and 403 for private addresses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019cgrVnvyqj7Q1ySUtBpVEj
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019cgrVnvyqj7Q1ySUtBpVEj
The default context still lists only the 8 seo_* tools; web tool state is created on first use and honours the context's network permissions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019cgrVnvyqj7Q1ySUtBpVEj
…commands Logs now go to stderr so stdout stays clean for Markdown and NDJSON. mcp gains --tools (default all) and --chrome-ws. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019cgrVnvyqj7Q1ySUtBpVEj
CI lints and tests with --all-features and builds and smoke-tests the image. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019cgrVnvyqj7Q1ySUtBpVEj
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019cgrVnvyqj7Q1ySUtBpVEj
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Local Chrome gets 45 s to start and one retry, background tabs are not throttled, the parallel-tab test compares finish times instead of total time, and Chrome tests run one at a time under nextest. CI now reports every failing test instead of stopping at the first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019cgrVnvyqj7Q1ySUtBpVEj
Command::new("bash") finds the WSL launcher in System32 first. Shell
scripts are also pinned to LF endings.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019cgrVnvyqj7Q1ySUtBpVEj
Shantodotdev
marked this pull request as ready for review
October 8, 2026 16:13
There was a problem hiding this comment.
Shantodotdev has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Shanto · project thread
Before: Black Sparrow could only audit sites for SEO. An agent that needed a page's content had to read raw HTML or pay for a crawling service like Firecrawl.
After: The same binary turns pages into clean Markdown and structured data for agents, with no LLM involved. It ships as six new CLI commands (
scrape,map,crawl,find,extract,interact), eightweb_*MCP tools, and a self-hosted HTTP API that accepts Firecrawl's request and response shapes, with a Docker image. The SEO audit is unchanged and its tests pass without edits.This implements Phases 0 to 6 of the agent crawler plan. The LLM fallback phase is skipped as requested. The full guide is in
docs/agent-mode.md.Note
The branch starts from Shanto's 16 local commits (SSRF egress protection, Chrome CDP rendering, 15 MB streaming limits, installer fixes,
cc7b4c4and earlier), which were not on GitHubmain. They show up in this PR's diff alongside the new work.What's new
PageDocument. Before fetching, it checks the network guard, the cache and robots.txt. It asks the server for Markdown first (Accept: text/markdown). PDFs are read withlopdf, and scanned PDFs come back asneeds_ocr. Bot challenge pages are reported asblocked. Chrome is used only for empty JavaScript app shells, or when the caller asks for it.rs-trafilaturaplus our own pass that drops text hidden by CSS oraria-hidden, so hidden prompt-injection text never reaches the agent. Output is GFM Markdown, typed blocks with heading paths, and token counts (tiktoken).--out), NDJSON, or background jobs that can be polled and cancelled and are stored in SQLite.__NEXT_DATA__and similar), selectors learned from pages of the same template, label/value pairs, OpenGraph, then page patterns. Every field reports its source and a confidence. Format recognisers handle prices, dates, phone numbers, GTIN/ISBN check digits and more.e12-style references from an accessibility snapshot, then reads the page. Chrome's requests go through the same private-network guard.--features serve, axum)/v1and/v2scrape,mapandcrawl;GET/DELETE /v1/crawl/{id}; and/v1/find,/v1/extract,/v1/interactand/health. Requires a bearer key, and refuses to bind beyond loopback when no keys are set. Each key has its own rate limit. Body size, pages per crawl and concurrent crawls are capped. Private addresses get a 403, and each request is logged in one line.web_*tools whose descriptions warn that page content is untrusted.blacksparrow mcp --tools seo|web|alldefaults toall. Library callers ofMcpContextstill get only the 8 SEO tools by default./datavolume,BLACKSPARROW_DB_PATH, and a health check. A compose file adds achromedp/headless-shellsidecar on a private network. Chromium is not bundled.--all-features, and nextest runs with--no-fail-fast. Chrome test binaries run one at a time (achrometest group in.config/nextest.toml). A new job builds the image and smoke-tests/healthand the 401 response.How
Phase 0 adds a
PageProcessorseam to the crawler and storage migrations for documents, chunks with FTS5, content crawls and learned rules. The rest of the work lives insrc/extract/(pipeline),src/serve/(HTTP),src/mcp/web_tools.rsandsrc/cli/agent.rs. Other changes:Crate choices:
dom_queryfor DOM queries,rs-trafilaturafor main-content detection,tiktoken-rs,globset,lopdf(no default features) andaxum0.8 (optional).Differences from Firecrawl:
/v1/extractis synchronous and returns{data, results}.jsonandsummaryformats need an LLM, so they are ignored.data:URIs.executeJavascriptactions are refused.Testing
CI is green on Ubuntu, macOS and Windows, and the Docker job builds the full image and passes its smoke test.
Locally, 319 nextest tests pass with
--all-featuresand Chrome available, plus 37 doc tests. Clippy is clean with-D warnings, andcargo fmtwas run.One existing test file changed:
tests/installer_tests.rs. On Windows runners,bashresolved to the WSL launcher in System32, so the installer help test failed. It now uses Git Bash there, and.gitattributeskeeps*.shfiles with LF endings. The assertions are unchanged. No SEO test was touched.New suites:
agent_scrape_testsagent_crawl_testsagent_find_testsagent_extract_testsagent_render_testsagent_pdf_testsagent_evalserve_testsmcp_web_testscli_agent_testsstorage_migration_testsLimits of this testing:
🤖 Generated with Claude Code
https://claude.ai/code/session_019cgrVnvyqj7Q1ySUtBpVEj
Generated by Claude Code