doc-harvester — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited doc-harvester (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Turn any documentation site into a folder of local markdown inside the user's project, so that during development the coding agent can grep and read the official docs instead of guessing or fetching pages one at a time.
A plain single-URL fetch fails on real doc sites for three reasons, and this skill is built to defeat all three: (1) one fetch only sees one page; (2) most modern docs are client-rendered single-page apps, so a raw fetch returns an empty HTML shell with no content; (3) content hidden behind tabs and nested sections is never discovered. The engine works around this with a ladder of strategies, cheapest and most reliable first.
The engine is the bundled script scripts/harvest.py (Python 3, standard library only — nothing to install for the common cases). Run it from the project root:
python3 <skill_dir>/scripts/harvest.py "<DOC_URL>" --out docs/vendor<skill_dir> is the directory containing this SKILL.md. <DOC_URL> can be any page of the target docs — the engine figures out the root itself. Output lands in docs/vendor/<platform>/.
The engine auto-selects a method and prints a final RESULT: line. Read it: it reports which method succeeded, how many pages were saved, and the output directory. Then read _index.md and skim llms-full.md in the output folder to confirm the content is real documentation and not an error page.
The engine tries each step below and stops at the first that yields content. Understanding the ladder helps when you need to intervene.
Docusaurus setups) publish the entire documentation as one LLM-ready file at /llms-full.txt. One request, the whole corpus. Always the best outcome — if you see a "Copy page" button or a Markdown/ChatGPT/Claude option on the docs site, this file very likely exists.
markdown and also assembles a merged llms-full.md.
robots.txt), then each page is fetched. For each URL it first tries the URL + ".md" source endpoint (Mintlify/Fern serve clean markdown there), and falls back to Jina Reader.
r.jina.ai renders the entry page(executing JavaScript, so SPAs work) and the engine crawls same-site documentation links breadth-first. Free, no API key.
npx sitefetch (needs Node).Best effort; output parsing is defensive.
You normally just run the script once and let it pick. Use --method <name> only to force a specific step for debugging.
If the RESULT: line says status=failed, the site is fully client-rendered with no llms.txt and no sitemap. Escalate in this order:
--method jina. If Jina was rate-limited (HTTP 429),wait a minute and retry, or raise --delay 1.0. A Jina API key removes the limit — if the user has one they can request a free key at jina.ai; the engine does not require it.
crawl4ai is a free, open-source crawler with a realheadless browser. It is not bundled because installing it downloads a browser (~150 MB) and its Python API changes between versions. Only use it if the steps above failed, and ask the user first before installing. Then:
pip install -U crawl4ai
crawl4ai-setup # installs the headless browser, one timeCheck the installed version's deep-crawl API (python3 -c "import crawl4ai, inspect" or the project README), then write a short script that deep-crawls the docs root, collects each result's .markdown, and saves the pages exactly the way harvest.py does — one .md per page under pages/, a merged llms-full.md, and an _index.md. Keep the same output layout so the rest of this skill's conventions still hold.
Report honestly what was and was not captured. A partial harvest (e.g. sitemap found but some pages 404'd) is still useful — say so rather than implying it is complete.
Everything goes under docs/vendor/<platform>/:
docs/vendor/<platform>/
llms-full.md the entire documentation merged into one file (best for grep / full reads)
pages/... one markdown file per page, mirroring the URL path (when pages were fetched)
_index.md table of contents — the site's own llms.txt when available
_meta.json source URL, method used, timestamp, per-page checksums--out changes the base directory and --name overrides the auto-derived platform folder name. Re-running overwrites the page files (a fresh snapshot) without deleting unrelated files.
Collecting the docs is only half the job; the point is that the in-repo agent consults them. After a successful harvest, do this so future development cross-checks the official docs:
grep inside docs/vendor/<platform>/ instead of re-fetching the web.
CLAUDE.md (orAGENTS.md / .cursorrules) exists at the project root, add a short line such as:
Official <platform> documentation is mirrored indocs/vendor/<platform>/. Consultllms-full.mdthere before implementing anything that touches the <platform> API.
This is what makes the coding agent reach for the local docs automatically.
llms-full.md now and confirm the keyfacts the current task depends on (auth, endpoints, rate limits) before writing code.
| Flag | Purpose | ||||
|---|---|---|---|---|---|
--out DIR | base output directory (default docs/vendor) | ||||
--name NAME | output sub-folder name (default: derived from the host) | ||||
| `--method auto\ | llms\ | sitemap\ | jina\ | sitefetch` | force one strategy (default auto) |
--max-pages N | cap pages fetched (default 1500) | ||||
--include-prefix /path | restrict the sitemap/jina crawl to one section | ||||
--delay SECONDS | politeness delay between requests (default 0.15; raise if throttled) | ||||
--quiet | reduce logging |
answer 200 OK with an HTML shell for any path — including a missing llms.txt. A candidate counts only if the body is non-trivial and not HTML.
--delay for small or rate-limitedsites rather than hammering them.
skill periodically so the local copy stays current with the upstream documentation.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.